美文网首页
前端面试题(三)

前端面试题(三)

作者: 月半女那 | 来源:发表于2019-05-17 00:08 被阅读0次

    1. 服务器端渲染(ssr:service side render)

    优点:

    • 解决白屏问题,提高首屏渲染速度
    • 可以直接渲染页面,利于seo优化
      主要技术:
      通过react提供的renderToString方法,接受一个react组件,返回一段html结构字符串
      renderToString:渲染时带data-reacId,这样会增增加流量,但是在客户端对比就会重新渲染
      re7ynderToStaticMarkUp:渲染时不带data-raectId,节省流量,但是在客户端重新渲染时会出现闪屏
      https://yq.aliyun.com/articles/641674
      https://www.cnblogs.com/Coding-net/p/5024756.html

    2. react-redux实现原理

    • redux作为一个通用模块,主要用来处理应用中state的变更,通过react-redux做连接
    • react-redux两个核心方法
      provider: 在最外层封装了整个应用,并向connect模块传递store
      connect: 1. 监听原组件,将state和action通过props的方式擦混入到原组件内部。2. 监听store tree变化,使其包装的原组建可以响应state变化

    3. react 高阶组件

    1. 属性代理:通过被包裹的react组件来操作props
    2. 反向继承: 高阶组件继承于被包裹的react组件

    4. router4 withRouter

    withRouter其实就是为了获取location,history, maatch 这些参数,其本质上就是一个高阶组件,提供一个context

    本文参考:https://segmentfault.com/a/1190000017140200

    webpack 参考资料https://www.jianshu.com/p/c395ec989abd

    4. 面向对象

    面向对象的两大概念:类和实例
    类:对象的类型模板
    实例: 根据类创建的对象
    虽然js没有类的概念,但是它使用构造函数(constructor)作为对象的模板


    new 创建一个对象都进行了哪些操作

    1. 创建一个空对象,用this变量引用该对象并继承该函数的原型
    2. 属性和方法加入到this的引用对象中
    3. 新创建的对象由this所引用,最后隐式的返回this
    function newObj(fun,argument){
      var obj = {};
      if(fun && typeof fun === 'function'){
        o.__proto__ == fun.prototype;
        fun.apply(o,argument);
        return o;
      }
    }
    

    如果构造函数内部由return语句,且return后面跟着一个对象,new 命令返回retrun 指定的对象,否则直接返回this

    5. 原型链

    image

    proto和prototype区别

    1. proto是普通对象的隐式属性,在new的时候,会指向prototype所指的对象
    2. proto实际上是某个实体对象的属性,而prototype则是属于构造函数的属性
      简而言之
    • 构造函数通过prototype属性访问原型对象
    • 实例对象通过[[prototype]]内部属性访问原型对象,浏览器实现了proto属性用于实例对象访问原型对象
    • object为构造函数的时候,是function的实例对象;function为构造函数时,function.prototype是对象,那么它就是object的实例对象

    5. 元素居中

    1.文本居中:text-align:center

    1. 图片居中:父级:text-align:center
    2. 块级元素居中:margin-left:auto;margin-right:auto
    3. 单行文本竖直居中,让height和line-height相等(如果不确定高度,可以用padding)

    6. vue双向绑定

    通过数据劫持结合发布者-订阅者模式来实现的,vue通过object.defineProperty()来实现数据劫持
    https://www.cnblogs.com/libin-1/p/6893712.html

    7. web攻击正怎么防御

    1. xss(跨站脚本攻击):例如在表单中提交含有可执行的javascript的内容文本,如果服务器端没有过滤或转义这些脚本,而这些脚本由通过内容的形式发布到了页面上,这个时候如果有其他用户访问这个网页,那么浏览器就会执行这些脚本,从而被攻击,从而获取用户的cookie等信息

    防御
    对于敏感的cookie信息,使用HttpOnly,使document对象找不到cookie
    对于用户输入的信息进行转义

    1. CSRF(跨站点请求伪造):CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。
      防御
    • 敏感信息使用验证码
    • 验证http referer字段(referer字段会记录http请求的来源地址)
    • 在请求地址中添加token验证(更多的是生成一个随机的token,在用户提交数据的同时提交这个token,服务器端比对后如果不正确,则拒绝执行操作。在用户登录之后,产生token 并放入session中,在每次请求时把token从session中拿出来,以参数的形式加入请求,在服务器端建立拦截器验证该token,token则通过,否则拒绝。但是这种方法也是有安全问题的,在某些网站支持用户发表链接的,那么黑客在该网站发布自己的个人网站地址,系统也会为这个地址后加上token,则黑客可以在自己的网站上得到这个token参数,从而发动CSRF攻击)
    • 在http头中自定义token属性并验证(把token作为自定义属性放在HTTP的头中,通过封装XMLHttpRequest可以一次性给所有请求加上token 属性。这样子token就不会暴露在浏览器地址中。)
      3.SQL注入:攻击者在提交表单的时候,在表单上面填写相关的sql语句,而系统把这些字段当成普通的变量发送给服务器端进行sql查询,则,由攻击者填写的sql会拼接在系统的sql语句上,从而进行数据库的某些操作。
      防御
    • 表单过滤,验证表单提交的合法性,对一些特殊字符进行转义处理
    • 数据库权限最小化
    • 查询语句使用数据库提供的参数化查询接口,不要直接拼接SQL

    https://blog.csdn.net/qq_27855219/article/details/88796366

    8. flex布局

    flex(flexible box)其中心思想是给予容器控制内部元素高度和宽度的能力
    https://www.cnblogs.com/nuannuan7362/p/5823381.html

    • 利弊
      布局更加精简,直接用css的方式,你不用再引入bootstraop,使用栅格系统。
      瑕疵就是,IE10及IE10以上才支持,所以目前主要应用在移动端上。
      flex默认存在两根轴:水平的主轴和垂直的交叉轴
      flex项目默认沿主轴排列
      在设置了flex布局之后子元素的float,clear, vertical-align都失效
      grid:网格容器(display:grid)

    9. 原型和原型链以及构造函数的关联

    1. js中所有函数都有一个prototype属性,这个属性引用一个对象(fun.prototype),即原型对象,简称为原型
    2. 所有原型都有constructor属性和proto属性
    3. constructor属性指向自己的继承父类(即它的构造函数的原型)
    4. js中一切皆对象,而对象都有一个proto属性,
    5. object.prototype的proto指向null(最顶级的原型对象),所有原型链的最顶层都是object.prototype
    6. 注意:A instanceof B 是检查A的原型链上是否存在B.prototype
      function是最顶层的构造方法,所有对象都由function方法构造,包括object方法,function 方法
      object对象和function方法是相互依赖的
      原型链只有在索引值的时候才会用到,如果我们尝试获取对象的某个属性值,但该对象中并没有此属性值,那么js就会在其原型链对象中找,如果还没有,那么会一直在原型链中找,直到object.prototype,如果该对象原型链中没有找到,则返回undefined

    9.柯里化函数

    柯里化:又称为部分求值,是把接受多个参数的函数变化成一个接受一个单一参数的函数,并且返回一个新的函数的技,新函数接受余下参数并返回运算结果
    其实质就是利用闭包的概念

    10. 箭头函数不能使用的情况

    1. 定义字面量方法
    const calculator = {
        array: [1, 2, 3],
        sum: () => {
            console.log(this === window); // => true
            return this.array.reduce((result, item) => result + item);
        }
    };
    
    console.log(this === window); // => true
    
    // Throws "TypeError: Cannot read property 'reduce' of undefined"
    calculator.sum();
    

    因为运行的时候this.array未定义,在执行calculator.sum()的时候this指向windo,原因是箭头函数把函数上下文绑定到了window上,解决方案:

    const calculator = {
        array: [1, 2, 3],
        sum() {
            console.log(this === calculator); // => true
            return this.array.reduce((result, item) => result + item);
        }
    };
    calculator.sum(); // => 6
    

    把箭头函数变成普通函数

    1. 定义原型方法
      箭头函数会陶制运行时的执行上下文错误
    function Cat(name) {
        this.name = name;
    }
    
    Cat.prototype.sayCatName = () => {
        console.log(this === window); // => true
        return this.name;
    };
    
    const cat = new Cat('Mew');
    cat.sayCatName(); // => undefined
    

    只要变成普通函数之后,被调用时的执行上下文就会指向新创建的cat实例

    1. 定义事件回调函数
    const button = document.getElementById('myButton');
    button.addEventListener('click', () => {
        console.log(this === window); // => true
        this.innerHTML = 'Clicked button';
    });
    

    应该修改为

    const button = document.getElementById('myButton');
    button.addEventListener('click', function() {
        console.log(this === button); // => true
        this.innerHTML = 'Clicked button';
    });
    

    在用户触发点击按钮的时候,事件回调函数中的this实际指向button

    1. 定义构造函数
      因为箭头函数在创建时this对象就绑定了,并不会指向对象实例
    const Message = (text) => {
        this.text = text;
    };
    const helloMessage = new Message('Hello World!');
    // Throws "TypeError: Message is not a constructor"
    

    11. apply,call,bind

    call,apply改变某个函数运行的上下文
    call,apply区别就是接受参数的方式不太一样
    call(this,arg1,arg2,...) -- call传递的是参数
    apply(this,[arg1,arg2,...]) -- apply传递的是数组

    bind会创建一个新函数,称为这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,

    相关文章

      网友评论

          本文标题:前端面试题(三)

          本文链接:https://www.haomeiwen.com/subject/wekgaqtx.html