最近在读《javascript高级程序设计》疏通经脉,经过写文的方式增强本身理解。javascript
在前端面试的问题中少不了this
指向的问题,而如下三种方法均可以改变this
指向:前端
apply()
和call()
两个方法的用途都是在特定的做用域中调用函数,实际上等于设置函数体内的this
对象的值。apply()
方法接受两个参数:java
thisArg
thisArg
该参数可选填,在func 函数
运行时使用的this
值。若是这个函数处于非严格模式下,则指定为null
或undefined
时会自动替换为指向全局对象,原始值会被包装。若是该参数缺失时则指向全局对象。面试
argsArray
argsArray
该参数可选填,接受一个数组或arguments(arguments知识传送门:javascript:函数属性梳理)。若是不填写则表明不须要传参。数组
let o1 = {
number: 100
}
let o2 = {
number: 200
}
function sum (num1, num2) {
console.log(num1 + num2 + this.number)
}
sum.apply(o1, [1, 10]) // 111 将this指向o1
sum.apply(o2, [1, 10]) // 211 将this指向o2
复制代码
apply()
不只能传参,最重要的是能够改变函数赖以运行的做用域!!!在上面的例子中,当传入o1
时,this.number
指向了o1
里的number
;当传入o2
时,this.number
指向了o2
里的number
。浏览器
理解了
apply()
,那理解call()
便不费吹灰之力。由于call()
与apply()
方法惟一的区别在于第二个参 接受参数的形式不一样,做用彻底相同。call()传递给函数的参数只能逐个列举出来,看下面的例子:bash
function sum (num1, num2) {
console.log(num1 + num2)
}
sum.call(o1, 1, 10) // 11
复制代码
bind()
方法建立一个新的函数,在调用时设置this
关键字为提供的值。并在调用新函数时,将给定参数列表做为原函数的参数序列的前若干项。和call()
与apply()
的区别在于:bind()
会建立一个原函数的拷贝
(绑定函数),拥有指定的this
值和初始参数,并返回这个函数。看下MDN里的描述:app
bind()
最简单的用法是建立一个函数,不论怎么调用,这个函数都有一样的this
值。JavaScript
新手常常犯的一个错误是将一个方法从对象中拿出来,而后再调用,指望方法中的this
是原来的对象(好比在回调中传入这个方法)。若是不作特殊处理的话,通常会丢失原来的对象。基于这个函数,用原始的对象建立一个绑定函数,巧妙地解决了这个问题:函数
this.x = 9; // 在浏览器中,this指向全局的 "window" 对象
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// 返回9 - 由于函数是在全局做用域中调用的
// 建立一个新函数,把 'this' 绑定到 module 对象
// 新手可能会将全局变量 x 与 module 的属性 x 混淆
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
复制代码
关于call、apply和bind函数的做用极其类似,但有不一样之处,关于如何更好运用还得在探索。post
参考资料:
种一棵树最好的时间是十年前。