You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functiongreet(){varreply=[this.animal,'typically sleep between',this.sleepDuration].join(' ');console.log(reply);}varobj={animal: 'cats',sleepDuration: '12 and 16 hours'};greet.call(obj);// cats typically sleep between 12 and 16 hours
在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window(或 global)对象。当类的方法中需要 this 指向类的实例时,显式地把 this 绑定到回调函数,就不会丢失该实例的引用。
functionLateBloomer(){this.petalCount=Math.ceil(Math.random()*12)+1;}// 在 1 秒钟后声明 bloomLateBloomer.prototype.bloom=function(){window.setTimeout(this.declare.bind(this),1000);};LateBloomer.prototype.declare=function(){console.log('I am a beautiful flower with '+this.petalCount+' petals!');};varflower=newLateBloomer();flower.bloom();// 一秒钟后,调用 'declare' 方法
实现 bind
bind 方法会创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
实现要点:
bind() 除了 this 外,还可传入多个参数;
bind 创建的新函数可能传入多个参数;
新函数可能被当做构造函数调用;
函数可能有返回值;
Function.prototype.myBind=function(context){// 调用 bind 的不是函数,需要抛出异常if(typeofthis!=="function"){thrownewError("Function.prototype.bind - what is trying to be bound is not callable");}// this 指向调用者varself=this;// 实现第2点,因为第1个参数是指定的this,所以只截取第1个之后的参数varargs=Array.prototype.slice.call(arguments,1);// 创建一个空对象varfNOP=function(){};// 实现第3点,返回一个函数varfBound=function(){// 实现第4点,获取 bind 返回函数的参数varbindArgs=Array.prototype.slice.call(arguments);// 然后同传入参数合并成一个参数数组,并作为 self.apply() 的第二个参数returnself.apply(thisinstanceoffNOP ? this : context,args.concat(bindArgs));// 注释1}// 注释2// 空对象的原型指向绑定函数的原型fNOP.prototype=this.prototype;// 空对象的实例赋值给 fBound.prototypefBound.prototype=newfNOP();returnfBound;}
注释1 :
当作为构造函数时,this 指向实例,此时 this instanceof fBound 结果为 true ,可以让实例获得来自绑定函数的值,即上例中实例会具有 habit 属性。
当作为普通函数时,this 指向 window ,此时结果为 false ,将绑定函数的 this 指向 context
注释2 :
修改返回函数的 prototype 为绑定函数的 prototype,实例就可以继承绑定函数的原型中的值,即上例中 obj 可以获取到 bar 原型上的 friend
call()
function.call(thisArg, arg1, arg2, ...)
thisArg:在 function 函数运行时使用的 this 值。如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
arg1, arg2, ...:指定的参数列表。
call() 提供新的 this 值给当前调用的函数/方法。
调用父构造函数
调用匿名函数
调用函数并且指定上下文的 'this'
调用函数并且不指定第一个参数
在非严格模式下,如果没有传递第一个参数,this 的值将会被绑定为全局对象。在严格模式下,this 的值将会是 undefined。
实现 call
使用一个指定的 this 值和一个或多个参数来调用一个函数。
实现要点:
apply()
apply() 函数的语法与 call() 几乎相同,但根本区别在于,call() 接受一个参数列表,而 apply() 接受一个参数的单数组。
apply() 方法调用一个具有给定 this 值的函数,以及以一个数组(或类数组对象)形式提供的参数。
apply(thisArg, argsArray)
thisArg:在 func 函数运行时使用的 this 值。如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。
可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象,如 fun.apply(this, new Array('eat', 'bananas'))。从 ECMAScript 第 5 版开始,可以使用任何种类的类数组对象,如使用 NodeList 或一个自己定义的类似 {'length': 2, '0': 'eat', '1': 'bananas'} 形式的对象。
用 apply 将数组各项添加到另一个数组
可以使用 push 一次将一个元素或多个元素追加到数组中。可是当 push 的参数是数组,它会将该数组作为单个元素添加。concat 方法可以实现需求,但它并不是将元素添加到现有数组,而是创建并返回一个新数组。使用 apply 则可以将元素追加到现有数组。
内置函数
对于一些需要写循环以遍历数组各项的需求,可以用 apply 完成以避免循环。
注意:如果按上面方式调用 apply,有超出 JavaScript 引擎参数长度上限的风险。
链接构造器
实现 apply
apply 和 call 一样,唯一的区别就是 call 是传入不固定个数的参数,而 apply 是传入一个数组。
实现要点:
bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
function.bind(thisArg, arg1, arg2, ...)
thisArg:调用绑定函数时作为 this 参数传递给目标函数的值。如果使用 new 运算符构造绑定函数,则忽略该值。当使用 bind 在 setTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者 thisArg 是null 或 undefined,执行作用域的 this 将被视为新函数的 thisArg。
arg1, arg2, ...:当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
返回值:返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。
bind() 函数会创建一个新的绑定函数(bound function,BF)。绑定函数是一个 exotic function object(怪异函数对象,ECMAScript 2015 中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数。
创建绑定函数
bind() 最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this 值。
偏函数
bind() 的另一个最简单的用法是使一个函数拥有预设的初始参数。只要将这些参数(如果有的话)作为 bind() 的参数写在 this 后面。
配合 setTimeout
在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window(或 global)对象。当类的方法中需要 this 指向类的实例时,显式地把 this 绑定到回调函数,就不会丢失该实例的引用。
实现 bind
bind 方法会创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
实现要点:
注释1 :
注释2 :
区别
参考:
解析 bind 原理,并手写 bind 实现
死磕 36 个 JS 手写题
The text was updated successfully, but these errors were encountered: