关于apply、call和bind的总结

基础知识不是你看了一遍书或者两篇文章就能掌握的。

之前看书看文章时,感觉自己看懂了就掌握了。呵呵!too young!too naive!

高程上面关于apply和call的知识点:

apply和call,这两个方法的用途都是在特定作用域中调用函数,实际上等于设置函数体内this对象的值(this 指当前对象,也就是正在调用这个函数的对象。)。

apply方法

apply方法接收两个参数:一个是在其中运行函数的作用域(this),另一个是参数数组。其中,第二个参数(可选)可以是Array的实例,也可以是arguments对象。

用apply改变this:

var jack = {
      name:'jack',
      age:28,
      sayName:function() {
            console.log(this.name);
      }
};
var juli = {
      name:'juli',
      age:25
};
jack.sayName();//jack
jack.sayName.apply(juli);//juli

用apply改变this并传入第二个参数

var ryo = {
    name:'隆',
    learn:function(para) {
        this.shill = para;
    }
};
var ken = {
    name:'肯'
}
//通过ryo的learn方法让ken学会波动拳
ryo.learn.apply(ken,['波动拳']);

call方法

call方法与apply方法的作用相同,他们的区别仅在于接收参数的方式不同。

对于call方法,第一个参数与apply方法的第一个参数意义相同。不同的是,在使用call方法时,传递给函数的参数必须逐个列举出来。

把上面的两个例子用call改写,结果完全一样。注意两者传入函数的参数的方式不同。

bind方法

bind方法会创建一个调用bind方法的函数的实例(返回一个绑定函数),该函数实例(绑定函数)的this为传入bind方法的第一个参数。当使用new 操作符调用该函数实例(绑定函数)时,第一个参数无效。

通过bind方法还可以预设返回的函数实例(绑定函数)的参数,方法是给bind方法传入除第一个参数以外的参数。

用bind创建一个原函数的实例:

var name = 'window对象';

function originalFun(para1,para2) {
    console.log(arguments);
    console.log(para1 + para2);
    console.log(this.name);
}

var funOne = originalFun.bind();

funOne(3,4);

调用funOne函数的输出结果:

创建funOne函数时,没有向bind方法中传入参数,funOne的this被设为window对象。

不过在严格模式下,不传入参数,返回的函数实例的this不会被设为window,以上代码运行时会报错 'Cannot read property 'name' of undefined'。

用bind创建一个原函数的实例并绑定一个this:

var name = 'window对象';
var person = {
    name:'Gilbert',
    age:15
};

function originalFun(para1,para2) {
    console.log(arguments);
    console.log(para1 + para2);
    console.log(this.name);
}

var funTwo = originalFun.bind(person);

funTwo(5,6);

调用funTwo函数的输出结果:

用bind创建一个原函数的实例并绑定一个this和预设第一个参数:

var name = 'window对象';
var person = {
    name:'Gilbert',
    age:15
};

function originalFun(para1,para2) {
    console.log(arguments);
    console.log(para1 + para2);
    console.log(this.name);
}

var funThree = originalFun.bind(person,10);

funThree(40);

调用funThree函数的输出结果:

 用new操作符调用绑定函数时,会忽视传入bind方法的第一个参数。

下面的例子根据MDN的例子改编而来:

var math = {
    name:'jojo'
}
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.toString = function() {
    console.log(this);
    console.log(this.x + ',' + this.y); 
};
var CopyPoint = Point.bind(math,0);
var aPoint = new CopyPoint(10);
aPoint.toString();//输出:{x:0, y:10}    0,10

承接上面的代码,不用new操作符调用绑定函数:

//不用new操作符调用绑定函数
CopyPoint(20);
console.log(math);//输出:{name:'jojo', x:0, y:20}

结束语

以上内容只是总结了apply、call、bind的最基础的知识,要想在项目中熟练地使用这三个方法还要有一定的经验积累。

 

(完)

相关文章:

1.【优雅代码】深入浅出 妙用Javascript中apply、call、bind

参考文章:

1.Function.prototype.call()

2.Function.prototype.apply()

3.Function.prototype.bind()

4.Javascript 严格模式详解

posted @ 2017-05-18 10:26  Fogwind  阅读(228)  评论(0编辑  收藏  举报