JavaScript 之 call apply bind
关键字 this 绑定的方法
this
的动态切换,固然为JavaScript创造了巨大的灵活性,但也使得编程变得困难和模糊。有时,需要把this
固定下来,避免出现意想不到的情况。JavaScript提供了call
、apply
、bind
这三个方法,来切换/固定this
的指向。
1. apply(thisArg[,args])
call(thisArgs [,args...]) 后面跟的是若干个参数列表 而 apply接收的是参数数组。
thisArgs指定了函数在运行期的调用者,也就是函数中的this对象,而参数列表会被传入调用函数中。thisArgs的取值有以下4种情况:
A): 不传,或者传null,undefined, 函数中的this指向window对象
B): 传递另一个函数的函数名,函数中的this指向这个函数的引用
C): 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean
D): 传递一个对象,函数中的this指向这个对象
这是call的核心功能,它允许你在一个对象上调用该对象没有定义的方法,并且这个方法可以访问该对象中的属性。
3. apply
apply(thisArgs[,args[]])
apply和call的唯一区别是第二个参数的传递方式不同,apply的第二个参数必须是一个数组,而call允许传递一个参数列表。值得你注意的是,虽然apply接收的是一个参数数组,但在传递给调用函数时,却是以参数列表的形式传递。
function b(x,y,z){
console.log(x,y,z);
}
b.apply(null,[1,2,3]); // 1,2,3
4. bind
bind(thisArgs [,args...])
bind是ES5新增的一个方法,它的传参和call类似,但又和call/apply有着显著的不同,即调用call或apply都会自动执行对应的函数,而bind不会执行对应的函数,只是返回了对函数的引用。其实,ES5引入bind的真正目的是为了弥补call/apply的不足,由于call/apply会对目标函数自动执行,从而导致它无法在事件绑定函数中使用,因为事件绑定函数不需要我们手动执行,它是在事件被触发时由JS内部自动执行的。而bind在实现改变函数this的同时又不会自动执行目标函数,因此可以完美的解决上述问题
当点击网页时,onClick被触发执行,输出onepixel p1 p2, 说明onClick中的this被bind改变成了obj对象,为了对bind进行深入的理解,我们来看一下bind的polyfill实现。
5. 应用场景
继承:因为JavaScript 没有类继承 也不能像java c# 一样。所有 我们可以使用call apply实现继承。
6. Function.prototype.bind
我们真正需要解决的是什么?
Function.prototype.bind() 是不支持IE8 以及以下的浏览器的。可以在MDN有一个很棒的资源。
适用的模式
click handlers(点击处理函数) 点击之后响应或记录事件。
setTimeout 可以实现此功能。