参考
- https://www.codementor.io/niladrisekhardutta/how-to-call-apply-and-bind-in-javascript-8i1jca6jp
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
区别
- Objects in JavaScript, these 3 methods are used to control the invocation of the function. call() and apply() were introduced in ECMAScript 3 while bind() was added as part of ECMAScript 5.(改变this指向)
- call/apply方法的区别只是第二个参数的不一样。
- You can use call()/apply() to invoke the function immediately.(call()和apply()当即执行,没有返回东西)
- bind()返回一个新的函数(相对于复制了一样的函数,this指向指定的对象,返回绑定后的函数。)注意,f1.bind(obj,...)后,obj.f1并不存在,因此只是改变了函数this的指向,并返回新的函数。
例子1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function foo(x,y) {
console.log((x+y)+this);
}
var obj = {
age:10,
sayHi:function () {
console.log("年龄是:"+this.age);
}
};
var f1 = foo.bind(obj, 100, 200);
f1(); // bind复制函数后,绑定到对象,而后返回新的绑定后的函数
obj.f1(); // Uncaught TypeError: obj.f1 is not a function , bind只是返回一个函数,改变了函数里的this指向,并无在obj中添加函数f1
// bind什么均可,由于改变的是this的指向,看下面的两个bind
// f1.bind('1',100,200)
// f1.bind(1,100,200)
var f2 = foo.call(obj, 100, 200);
f2(); // Uncaught TypeError, 由于call没有返回值
var f3 = foo.apply(obj, [100, 200]);
f3(); // Uncaught TypeError, 由于apply没有返回值
</script>
</head>
<body>
</body>
</html>
例子2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//构造函数
function F1() {
// 一个随机数
this.number=Math.ceil(Math.random()*10)+1;
}
//原型中添加了一个方法
F1.prototype.show1=function () {
//this---->实例对象
window.setTimeout(this.show2.bind(this),1000);
// 由于 var f = this.show2只是一个function,f.bind(this)就将this指向了F1的实例对象。否则没有bind的话,f传进去window.setTimeout,this指向window。
};
//原型中添加了一个方法
F1.prototype.show2=function () {
//this---->实例对象
//输出了本身产生的随机数
console.log(this.number+"产生了一个数字");
};
var f1=new F1();
f1.show1();
</script>
</head>
<body>
</body>
</html>