JS-每周3到面试题(第6周)

150 阅读2分钟
  1. 说一下对bind,call,apply三个函数的认识,自己实现一下bind方法

    bind、call和apply都是可以改变函数中this指向的方法,关于this指向问题请看这里

    1. bind和call&apply的区别是,bind改变了this指向但不会立即执行,而apply和call方法是即改变了this指向,又立即执行的。
    2. call和apply的区别是参数
        var max1 = Math.max.call(null, 1,2,3); 
        var max2 = Math.max.apply(null, [1,2,3]);
    

    call的第二个参数是一个参数列表,apply的第二个参数是一个数组对象

    1. 实现bind
        Function.prototype.myBind = function (obj, ...arg1) {
            return (...arg2) => {
                let args = arg1.concat(arg2)
                let val
                // 因为o.fn.myBind(test,1,2),这里this的调用位置是o.fn,所以this指向o.fn,也就是obj._fn_ = o.fn
                obj._fn_ = this 
                val = obj._fn_(...args)
                delete obj._fn_
                return val
            }
        }
    

    检测一下

    //测试
    let test = {
        name: 'test'
    }
    let o = {
        name: 'o',
        fn: function () {
            console.log(this.name, ...arguments);  //这里把参数显示一下
        }
    }
    
    let b = o.fn.myBind(test,1,2)
    b() // "test" 1 2
    b(3,4) // "test" 1 2 3 4
    
  2. 对前后端跨域可以说一下吗?跨域分哪几种类型,如何解决各个跨域的问题。

跨域问题是由于js语言安全限制中的同源策略造成的,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合.

不同情况的跨域

  1. 同一域名,不同端口
  2. 同一域名,不同协议
  3. 域名和域名对应ip
  4. 主域相同,子域不同
  5. 同一域名,不同二级域名
  6. 不同域名

解决跨域的方法

  1. jsonp 动态创建script标签
  2. cors 服务端设置 Access-Control-Allow-Origin
  3. postMessage
  4. websocket
  5. Node中间件代理(两次跨域) 服务器向服务器请求就无需遵循同源策略
  6. nginx反向代理 原理类似node
  7. window.name + iframe
  8. location.hash + iframe
  9. document.domain + iframe

总结

  • CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
  • JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
  • 不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。
  • 日常工作中,用得比较多的跨域方案是cors和nginx反向代理
  1. 动手实现一个new操作符
    //简洁版的new操作符实现过程
    function newFunc(constructor, ...args) {
        //第一步:创建一个空对象obj 
        var obj = Object.create(null)
        
        //第二步:将构造函数 constructor的原型对象赋给obj的原型
        obj.__proto__ = constructor.prototype;
        
        //第三步:将构造函数 constructor中的this指向obj,并立即执行构造函数内部的操作
        constructor.call(obj, ...args);
        
        //第四步:返回这个对象
        return obj
    }
    
    function constr (name, age) {
        this.name = name
        this.age = age
    }
    
    let res = newFunc(constr, 'zed', 18)
    console.log(res, res.name)

结果