首先,call、apply、bind都可以改變函數運行時this的指向問題
<script>
var value = "王1";
var obj = {
value: "開2",
friend: {
value: "貴3",
sayHi: function () {
console.log(this.value);
}
}
};
obj.friend.sayHi();//打印貴3
obj.sayHi = obj.friend.sayHi;
//誰調用this就屬於誰
obj.sayHi();//打印開2
//window
var sayHi = obj.friend.sayHi;
sayHi();//打印王1
console.dir(sayHi);//dir查看結構
//call()參數1是你要修改的this
var obj2 = { value: "星星" };
sayHi.call(obj2);
sayHi.apply(obj2);
function sayHello(a, b) {
console.log(this, "jom", a, b)
}
sayHello(10, 20);
//call:從參數2開始,就是對應原函數的參數
sayHello.call(obj2, 96, 72);
//apply:參數2是個數組,數組位置對應原函數參數
sayHello.apply(obj2, [66, 888]);
//數組元素對應的形參,藉助apply
var numbers = [9, 1, 20, 30, 100]
var min = Math.min.apply(Math, numbers);
console.log(min);
//es6的解構賦值
var min = Math.min(...numbers);
console.log(min);
//bind函數
//bind 方法不會立即執行,而是返回一個改變了上下文 this 後的函數
var fn = sayHello.bind(obj, 111, 222);
fn();
setTimeout(function () {
console.log(this);//window
}.bind(obj2), 2000);
</script>
通過上面的例子可以看出call、apply和bind函數存在的區別:
bind方法不會立即執行,返回一個改變了上下文的this後的函數, 便於稍後調用; apply, call則是立即執行。
除此外, 在 ES6 的箭頭函數下, call 和 apply 將失效, 對於箭頭函數來說:
// 箭頭函數體裏面的 this 對象, 是定義時所在的對象,
// 箭頭函數不能用作構造函數,也就是說不能使用 new 命令
// 箭頭函數不可以使用 arguments 對象