JS中call()、apply()、bind()的用法和区别

本文深入解析JavaScript中call、apply和bind三大方法,详细阐述它们如何改变函数内的this指向,包括各自的语法、应用场景及区别。并通过实例演示如何用于方法调用替换、对象继承和多重继承,以及常见用法如数组操作、类型检测等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在JavaScript中,callapplybindFunction对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向。

一、方法定义

call方法:

语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])

定义:调用一个对象的一个方法,以另一个对象替换当前对象。

说明: call 方法可以用来代替另一个对象调用一个方法。
call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

thisObj的取值有以下4种情况:
(1) 不传,或者传null,undefined, 函数中的this指向window对象
(2) 传递另一个函数的函数名,函数中的this指向这个函数的引用
(3) 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean
(4) 传递一个对象,函数中的this指向这个对象

apply方法:

语法:apply([thisObj[,argArray]])

定义:应用某一对象的一个方法,用另一个对象替换当前对象。

说明:如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

call 和 apply的区别
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。

bind方法:

语法:bind([thisObj[,arg1[, arg2[, [,.argN]]]]])() 或者 bind([thisObj[,argArray]])()

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

说明:bind是在EcmaScript5中扩展的方法(IE6,7,8不支持),bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

注意:bind方法的返回值是函数

二、常用实例

1、函数也是对象,函数的调用替换用法:

function add(a,b){  
    alert(a+b);  
}  
function sub(a,b){  
  alert(a-b);  
}  
//call的用法
add.call(sub,3,1); //alert(4)
//apply的用法
add.apply(sub,[3,1]); //alert(4)
//bind的用法
add.bind(sub,3,1)(); //alert(4)
add.bind(sub,[3,1])(); //alert(3,1undefined)

 通过call、apply或bind方法,用 add 来替换 sub方法。

2、对象的方法调用替换用法:

function Animal(){    
    this.name = "Animal";    
    this.showName = function(){    
        alert(this.name);    
    }    
}    
function Dog(){    
    this.name = "Dog";    
}    
var animal = new Animal();    
var dog = new Dog();     
//call的用法
animal.showName.call(dog,“”); //alert(Dog)
//apply的用法
animal.showName.apply(dog,[]); //alert(Dog)
//bind的用法
animal.showName.bind(dog,“”)(); //alert(Dog)
animal.showName.bind(dog,[])(); //alert(Dog)

 通过call、apply或bind方法,将原本属于Animal对象的showName()方法交给对象dog来使用了。

3、实现继承:

 

function Animal(name){    
    this.name = name;    
    this.showName = function(){    
        alert(this.name);    
    }    
}
//call的用法   
function Dog(name){    
    Animal.call(this, name)  
}       
var dog = new Dog("Dog");     
dog.showName(); //alert(Dog)
//apply的用法
function Dog2(name){    
    Animal.apply(this, [name])  
}       
var dog2 = new Dog2("Dog");     
dog2.showName(); //alert(Dog)
//bind的用法
function Dog3(name){    
    Animal. bind(this, name)()  
}       
var dog3 = new Dog3("Dog");     
dog3.showName(); //alert(Dog)

function Dog4(name){    
    Animal. bind(this, [name])()  
}       
var dog4 = new Dog4("Dog");     
dog4.showName(); //alert(Dog)

4、多重继承的实现

function Animal(name){    
    this.name = name;    
    this.showName = function(){    
        alert(this.name);    
    }    
}
function Pet(food){    
    this.food = food;    
    this.loveEat = function(){    
        alert(this.food);    
    }    
}
//这里只写一下call的用法 ,apply和bind的用法大家可以自己写一下  
function Dog(name,food){    
    Animal.call(this, name);
    Pet.call(this, food);
}       
var dog = new Dog("Dog","Bone");     
dog.showName(); //alert(Dog)
dog.loveEat(); //alert(Bone)

5、列举常用的一些方法

 

为了巩固加深记忆,下面列举一些常用用法:

a.数组之间追加

var array1 = [12 , "foot" , {name:"tom"} , true]; 
var array2 = ["Do" , 123 , 456, false]; 
Array.prototype.push.apply(array1, array2); 

 array1 的值为:[12, "foot", {name:"tom"}, true, "Do", 123, 456, false]

b.获取数组中的最大值

var  numbers = [3, 4 , 5 , -9 ]; 
var maxInNumbers = Math.max.apply(Math, numbers);  //5
    console.log(maxInNumbers);
    maxInNumbers = Math.max.call(Math,3, 4 , 5 , -9 ); //5
    console.log(maxInNumbers);

 

number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。最小值也是一样的实现方式。

c.验证是否是数组(前提是toString()方法没有被重写过)

function isArray(obj){  
   return Object.prototype.toString.call(obj) === '[object Array]' ;
}
var a = [1,2,3,4,55];
isArray(a);   //true

 

d.类(伪)数组使用数组方法


var domNodes = Array.prototype.slice.call(document.getElementsByTagName("div"));

 

Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。

但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值