call / apply / bind
发布时间:2020-12-14 04:34:13 所属栏目:大数据 来源:网络整理
导读:对于 call / apply / bind 来说,他们的首要目的是用于改变执行上下文的 this 指针。 call / apply 对 call / apply 的使用,一般都如下,用于改变执行环境的上下文。只是 call 接受的是一个一个的参数,而 apply 则是接受的是一个参数数组。 const obj1 = {
对于 call / apply / bind 来说,他们的首要目的是用于改变执行上下文的 this 指针。 call / apply对 call / apply 的使用,一般都如下,用于改变执行环境的上下文。只是 call 接受的是一个一个的参数,而 apply 则是接受的是一个参数数组。 const obj1 = { a: 1,myFunc(var1) { console.log(this.a + var1) } } const obj2 = { a: 2 } const myFunc = obj1.myFunc myFunc(1) // NaN obj1.myFunc(1) // 2 myFunc.call(obj2,1) // 3 myFunc.apply(obj2,[1]) // 3 bindbind 是 ES2015 出的一个方法,也是用于改变函数内部的 this 指向。但不一样的是,bind 方法不是直接执行的,而是生成一个新的已被改变过的函数。 const obj1 = { a: 1,myFunc(var1) { console.log(this.a + var1) } } const obj2 = { a: 2 } const myFunc = obj1.myFunc const bindMyFunc1 = myFunc.bind(obj1) const bindMyFunc2 = myFunc.bind(obj2) myFunc(1) // NaN bindMyFunc1(1) // 2 bindMyFunc2(1) // 3 通过上面的例子就可以看出来,bind 方法就可以生成一个新的 this 指向的 function。 手动写 bind 函数仅仅作为简单实现的话,我们仅需要注意改变 this 指向和预置参数即可。 function bind(fn,_this,...args) { if(typeof fn !== 'function') { throw new Error('bind fn need to be function') } return function(...innerArgs) { return fn.apply(_this,[...args,...innerArgs]) } } 当然这个手动实现的 bind 方法是只实现了最主要的功能,对函数的原型链和作为构造函数的方式都是没有考虑到的。这里可以参考 MSDN 的 polyfill 方法。 if (!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if (typeof this !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var aArgs = Array.prototype.slice.call(arguments,1),fToBind = this,fNOP = function() {},fBound = function() { // this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用 return fToBind.apply(this instanceof fBound ? this : oThis,// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的 aArgs.concat(Array.prototype.slice.call(arguments))); }; // 维护原型关系 if (this.prototype) { // Function.prototype doesn't have a prototype property fNOP.prototype = this.prototype; } // 下行的代码使fBound.prototype是fNOP的实例,因此 // 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例 fBound.prototype = new fNOP(); return fBound; }; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |