js 中call,apply,bind的区别

时间:2023-02-16 00:21:43

call、apply、bind方法的共同点与区别:

apply、call、bind 三者都是用来改变函数的this对象的指向;

apply、call、bind 三者都可以利用后续参数传参;

bind 是返回对应函数,便于稍后调用;apply、call则是立即调用。

一、call

1、   call(thisObj,x,y)

thisObj的取值有以下4种情况:

(1)不传,或者传null,undefined,函数中的this指向window对象;

(2)传递另一个函数的函数名,函数中的this指向这个函数的引用;

(3)传递字符串、数值或者布尔类型等基础类型,函数中的this指向其对应的包装对象,如string、number、boolean

(4)  传递一个对象,函数中的this指向这个对象

function a(){
console.log(this);
} function b(){} var c={name: 'call'}; a.call(); // window
a.call(null); //window
a.call(undefined) //window
a.call(1); // Number
a.call(''); // String
a.call(true) // Boolean
a.call(b) // function b(){}
a.call(c) // Object

2、 举个例子:

function Animal(){
this.name="animal";
this.showName=function(){
console.log(this.name);
}
}
function Dog(){
this.name = "dog";
}
var animal=new Animal();
var dog = new Dog();
animal.showName.call(dog); 返回的是dog

因为dog继承了animal中showName 这个方法,但是this的指向还是dog,所有打印出来的是dog 中的name.

3、 call()在继承中的运用

function Animal(name) {
this.name=name;
this.showName=function(){
console.log(this.name);
}
}
function Dog(name){
Animal.call(this,name);
}
var dog = new Dog("Crazy dog");
dog.showName();
}
输出:Crazy dog

传入了name 这个参数。

二、apply()

apply(thisObj,[argArray])

如果argArray 不是一个有效的数组或者不是arguments对象,那么将导致一个TypeError。

如果没有提供argArray 和thisObj 任何一个参数,那么Global对象将被用作thisObj, 并且无法被传递任何参数。

call 与apply 用法几乎是一样,只是传参的方式不一样。在js中,如果某个参数数量是不固定的,适合用apply,可以把参数push 进数组,传递进去。如果参数的数量是明确的,那就可以用cal。

三、bind

1、bind是在ES5 中扩展的方法(IE6,7,8不支持)

bind()方法与apply 和call很相似,也是可以改变函数体内的this的指向。

MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

var bar=function(){
console.log(this.x)
} var foo={
x:3
}
bar()
bar.bind(foo)(); var func=bar.bind(foo);
func() 输出:
undefined
3

2、如果连续bind()两次,艺或者是连续bind()三次,那么输出的值是什么?

var bar = function(){
console.log(this.x)
}
var foo = {
x:3
}
var sed = {
x:4
}
var func = bar.bind(foo).bind(sed);
func();//
var fiv = {
x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func();

答案都是3。原因是,在js中,多次bind()是无效的。

四、总结apply、call、bind比较

var obj = {
x: 81
} var foo = {
getX: function() {
return this.x;
}
} console.log(foo.getX.bind(obj)()); //
console.log(foo.getX.call(obj)); //
console.log(foo.getX.apply(obj)); //

三个输出是81,但是注意看使用bind()方法,后面多了对括号。

区别是:当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用bind()方法。而apply/call则会立即执行函数。

再总结一下:

apply、call、bind 三者都是用来改变函数的this对象的指向的;

apply、call、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

apply、call、bind 三者都可以利用后续参数传参;

bind是返回对应函数,便于稍后调用;apply、call则是立即调用。