JS中的call( )方法和apply( )方法以及bind()

本文详细介绍了JavaScript的call和apply方法,包括它们改变this指向的作用、区别(call以散列形式传参,apply用数组),并通过实例演示了在实际开发中的应用场景,如判断数据类型、转换伪数组和构造函数继承。

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

一. call和apply的作用

运用call()和apply()以及bind()这三个方法,都是为了改变this的指向

语法都是:函数.call(),函数.apply(),函数.bind()

二. call和apply的区别

call,apply可以立即执行,bind不会立即执行(因为bind返回的是一个函数需要加入()执行)

它们的第一个参数都是this要指向的对象,不同的是,call方法传递函数调用形参是以散列形式,apply方法的形参是一个数组。在传参情况下,call的性能要高于apply,因为apply在执行时还多一步解析数组。

举例一

let person = {
    getName:function(){
        return this.name
    }
}
let person1 = {
    name:'李莲花'
}
console.log(person.getName()) //这个时候的this指向的是window
console.log(person.getName.call(person1)) //这个时候的this指向的是person1

// 打印出undefined
// 打印出李莲花

举例二 

    var obj={
        name:"李相夷",
        age:18
    }
    function method(){
        console.log(this) //window
    }
    method()

上面的this指向的是window,如何让他指向对象obj呢?

1. 使用call

    var obj={
        name:"李相夷",
        age:18
    }
    function method(a,b,c){
        console.log(this,a,b,c) //{name: "李相夷", age: 18} 1 2 3
    }
    method.call(obj,1,2,3)

2. 使用apply

    var obj={
        name:"李相夷",
        age:18
    }
    function method(a,b,c){
        console.log(this,a,b,c) //{name: "李相夷", age: 18} 1 2 3
    }
    method.apply(obj,[1,2,3])

三. 实际开发过程中的使用场景

1. 使用call实现判断复杂数据类型

console.log(Object.prototype.toString.call({}) === '[object Object]') // ture
console.log(Object.prototype.toString.call([]) === '[object Array]') // true

2. es5把伪数组转为真正的数组 

function get () {
    console.log(arguments)
    // 方法一
    console.log([...arguments])
    // 方法二
    console.log(Array.prototype.slice.call(arguments))
}
get(1,2,3)

 

3. JS的继承,构造函数的继承就是靠call来实现的 

function Animal(name){
    this.name = name
    this.showName = function (){
        console.log(this.name)
    }
}
function Cat(name){
    Animal.call(this,name)
    // 使用this对象代替Animal对象,Cat中就有了Animal的所有属性和方法
}
let cat = new Cat('Tony')
cat.showName()  // 打印出Tony

必须用apply的情况(因为apply第二个参数是数组)

<script>
var arr1 = [1,2,4,5,7,3,321];
console.log(Math.max(1,2,4,5,7,3,321)); // 打印出321
console.log(Math.max(arr1)); // 这样写是找不到arr的,所以会打印出NAN
/* 此时就需要用到apply */
console.log(Math.max.apply(null,arr1)); // 打印出321
</script>

必须用bind的情况(因为bind返回的是一个函数,需要加入()执行)

<body>
  <div id="btn">按钮btn</div>
  <div id="atm">按钮atm</div>
  <script>
   var btn = document.getElementById("btn");
   var atm = document.getElementById("atm");
   btn.onclick = function(){
      console.log(this); // 此时打印出的结果是:<div id="btn">按钮btn</div>
   }
  </script>
</body>

/* 想让其打印出atm的dom */
<body>
  <div id="btn">按钮btn</div>
  <div id="atm">按钮atm</div>
  <script>
   var btn = document.getElementById("btn");
   var atm = document.getElementById("atm");
   btn.onclick = function(){
      console.log(this); // 此时打印出的结果是:<div id="atm">按钮atm</div>
   }.bind(atm)
  </script>
</body>
// 因为function(){}.bind()正好返回的是一个函数,而我们恰好需要通过等待点击事件onclick去触发函数,如果不用bind,而是用call或者apply,那它两是立即执行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值