node.js学习笔记之call,apply,bind

node.js中一切都是对象,那理所当然的函数也是一个对象,是对象就会有自己的方法,所有的函数都少不了这三个方法,call,apply,bind。

我们提供的服务有:成都网站建设、成都网站设计、微信公众号开发、网站优化、网站认证、封丘ssl等。为成百上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的封丘网站制作公司

我个人学完这三个方法之后有一点自己自己的理解,我的理解就是这三个方法都是为了绑定this对象并执行该函数。当然三个方法也有不同之处,我先来说说相同的地方,也就是如何绑定this对象的。

call:

//代码1
'use strict';

function test(xx,yy){
	this.x = xx;
	this.y = yy;
}

let a = {};
test.call(a,10,20);
console.log(a); //{x:10,y:20}

如上代码,我用了ES6的let,"use strict"是开启了严格模式,然后定义一个函数test,有两个参数xx,yy,然后定义了一个对象a,没有属性,当执行test.call(a,10,20);这句代码的时候就会把a传到函数test里并和this绑定,然后传参数10和20,这样就相当于

//代码2
let a = {};
function test(xx,yy){
	a.x = xx;
	a.y = yy;
}
test(10,20);
console.log(a); //{x:10,y:20}

于是,a对象就有了 x 和y属性。

再看apply:

//代码3
'use strict';

function test(xx,yy){
	this.x = xx;
	this.y = yy;
}
let a = {};
test.apply(a,[10,20]);
console.log(a);//{x:10,y:20}

这段代码和上面的基本上一样,只有一句不一样的:

test.apply(a,[10,20]);

它实际上也是相当于代码2的,在这里,相信大家也能看出来call 和apply 的区别了,就是传参方式不太一样,call方法是先传一个对象和this绑定,然后再依次传入test函数所需要的参数,而apply是先传一个对象和this绑定,然后把test函数所需要的参数都打包到一个数组中,由apply方法去展开数组再依次传入test方法。他们两个的区别就在这。

下面再看bind:

function test(xx,yy){
	this.x = xx;
	this.y = yy;
}
let a = {};
let b = test.bind(a,10,20);
b();
console.log(a);//{x:10,y:20}

和上面两个兄弟不一样的地方在于

let b = test.bind(a,10,20);
b();

bind的传参方式是和call一样的,但他会返回一个函数存于b中,而b函数你完全可以不用立即执行,这也是bind和call,apply不同的地方。

关于这点我有一些个人理解,当执行了let b = test.bind(a,10,20);之后,实际上应该是返回了一个函数对象,于是上面两行代码就可以大致看做:

let b = function test(xx=10,yy=20){
	a.x = xx;
	a.y = yy;
}

然后执行b();a就会多了两个属性x,y,这两个属性也有了值10和20,在这里需要重点说一下,如果不执行b();a是不会有变化的。

在本文最开始说在js中一切都是对象,于是我就有了一个奇怪的想法,既然b也是一个函数,那他应该也会有bind方法吧,于是我就又继续写了如下代码:

'use strict';

function func(name,xx,yy){
	this.name = name;
	this.x = xx;
	this.y = yy;
}
let a = {};
let b = {};
let d = func.bind(a,'a',10,20);
d();
let f = d.bind(b,'b',10,20);
f();
console.log(a,b);

你猜结果会如何?会不会{name:'a',x:10,y:20}{name:'b',x:10,y:20}呢?结果....果然出乎我的意料:{name:'a',x:10,y:20}{},后来我仔细想想这是为什么,恩,于是我就想到

let b = function test(xx=10,yy=20){
	a.x = xx;
	a.y = yy;
}

这一段,既然函数里面的this已经是a了,那就没有this了,再传b进去也绑不了this了,所以b才会没有属性。

关于这一点不知道我想的对不对,希望有大神能给予指点。本文参考http://developer.51cto.com/art/201503/466978.htm


分享名称:node.js学习笔记之call,apply,bind
链接地址:http://pwwzsj.com/article/jgdgpi.html