node.js中一切都是对象,那理所当然的函数也是一个对象,是对象就会有自己的方法,所有的函数都少不了这三个方法,call,apply,bind。
我个人学完这三个方法之后有一点自己自己的理解,我的理解就是这三个方法都是为了绑定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
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。