new 操作符的原理&&call,bind,apply运用

187 阅读2分钟

new操作符

还是实战操作模拟new一个数组吧。

首先我们定义数组的构造函数,如下:

function _Array(){
    // 如果参数为1,则定义数组长度,否则,将参数添加入数组
    // arguments为传入的参数迭代
    if(arguments.length > 1){
        for(let i of arguments){
            this.splice(this.length,0,i)
        }
    } else {
        this.length = arguments[0]
    }
}

然后,来模拟一下new函数。如下:

function _new(){ 
    // 第一步:创建一个空对象
    let obj = [];
    // 第二步:提取出构造函数
    let [constructor,...args] = [...arguments];
    
    // 第三步:将新对象的原型链指向构造函数的原型
    obj.__proto__ = constructor.propotype;
    
    // 第四步:执行构造函数中的代码,传入参数,对新对象初始化
    constructor.apply(obj,args)
    
    // 第五步:返回新对象
    return obj
}

最后,控制台打印如下:

let arr = _new(_Array,1,2)
console.log(arr) // [1,2]

bind,call,apply的区别?

JavaScript 的一大特点是函数存在:

  • 定义时上下文

  • 运行时上下文

  • 上下文是可以改变

call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。

apply

apply接受两个参数,第一个参数是this的指向,第二个参数是函数接受的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,默认指向window(在浏览器中),使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。

call

call方法的第一个参数也是this的指向,后面传入的是一个参数列表(注意和apply传参的区别)。当一个参数为null或undefined的时候,表示指向window(在浏览器中),和apply一样,call也只是临时改变一次this指向,并立即执行。

bind

bind方法和call很相似,第一参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

ar arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参

可以看出,bind方法可以分多次传参,最后函数运行时会把所有参数连接起来一起放入函数运行。

区别?

call ,apply 方法是一样的只是传递的参数不同

call(obj,args1,args2)
apply(obj,[args1,args2]) ,

bind方法可以分多次传参, bind调用完成后不执行,call,apply是马上执行。