javascript的中call、apply、bind

javascript的中call、apply、bind

js中,callapplybind 是三个很重要的函数方法,它们主要用于改变函数的执行上下文(context)和传参。其作用是类似的,但有些细节上是不同的。下面我将用几个小例子讲解它们的区别和用法。

call

call() 方法在一个对象上调用另一个对象的方法。在调用时,将 this 关键字设置为指定的值,并且可以传递参数作为一个列表。

语法:function.call(thisArg, arg1, arg2, ...)

  • thisArg:传递给函数的对象,可以设置为 null 或 undefined。
  • arg1, arg2, ...:传递给函数的参数列表。

例子:

const person = {
  name: "jack",
  age: "18",
  sayHello: function () {
    console.log(`Hello, my name is ${this.name}`);
  },
};
const alice = { name: "Alice" };
person.sayHello()
person.sayHello.call(alice); // Hello, my name is Alice

在这个例子中,定义了一个 person对象和sayHello() 函数,它会输出一个问候语。然后创建了一个对象 alice,它有一个 name 属性。然后使用 call() 方法来调用 person对象的sayHello() 函数并设置 this 关键字为 alice 对象。这样,它会输出 Hello, my name is Alice!

使用 call() 方法实现类继承的功能的例子:

function Animal(name) {
  this.name = name;
}
Animal.prototype.sayName = function() {
  console.log(`My name is ${this.name}.`);
};

function Cat(name, color) {
  Animal.call(this, name);
  this.color = color;
}

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

const cat = new Cat('Kitty', 'white');
cat.sayName();  // My name is Kitty.

在这个例子中,定义了一个 Animal 类和一个 Cat 类。Animal 类有一个 sayName() 方法,输出动物的名字。Cat 类继承自 Animal 类,并在构造函数中调用了 Animal 类的构造函数,并传递了 thisname 参数。然后,将 Cat 类的原型对象设置为 Animal 类的原型对象的一个新实例,并将 constructor 属性设置为 Cat。这样,Cat 类就具有了 Animal 类的 sayName() 方法。

apply

apply() 方法与 call() 方法类似,都是用来调用函数并改变函数的执行上下文和传递参数。不同之处在于,apply() 方法接受一个参数数组作为函数的参数,而 call() 方法则是将每个参数都显式地传递给函数。

语法:function.apply(thisArg, [argsArray])

  • thisArg:传递给函数的对象,可以设置为 null 或 undefined。
  • argsArray:传递给函数的参数

例子:

function sayHello(msg1, msg2) {
  console.log(`${message}, ${this.name}${punctuation}`);
}
const person = {
  name: 'jack'
};

sayHello.apply(person, ['Hello', '!']);  // Hello, jack!

在这个例子中,定义了一个 sayHello() 函数,它接受两个参数:msg1msg2。然后,创建了一个对象 person,它有一个 name 属性。接着,使用 apply() 方法来调用 sayHello() 函数并设置 this 关键字为 person 对象,并将 msg1msg2 参数作为一个数组传递给函数。这样当 sayHello() 函数执行时,它会输出 Hello, jack!

下面是一个例子,将一个数组的最大值传递给 Math.max() 函数:

const num = [1,2,3,4,5,6,7];
const max = Math.max.apply(null, num);
console.log(max);  // 7

在这个例子中,使用 apply() 方法将 numbers 数组的值作为参数传递给 Math.max() 函数。在这里将 null 作为第一个参数传递给 apply() 方法,因为 Math.max() 函数不需要使用 this 关键字。

bind

bind() 方法不会立即调用函数,而是创建一个新的函数,其 this 关键字设置为指定的值,可以传递一些参数作为默认值。

语法:function.bind(thisArg[, arg1[, arg2[, ...]]])

  • thisArg:传递给函数的对象,可以设置为 null 或 undefined。
  • arg1, arg2, ...:传递给函数的参数列表。

例子:

function sayHello(msg) {
  console.log(`${msg}, ${this.name}!`);
}
const person = {
  name: 'jack'
};
const greetPerson = sayHello.bind(person, 'Hello');
greetPerson();  // Hello, jack!

在这个例子中,定义了一个 sayHello() 函数和一个 person 对象。然后,使用 bind() 方法创建了一个新函数 greetPerson,其 this 关键字设置为 person 对象,并将 message 参数设置为 Hello。最后,调用 greetPerson() 函数,并输出 Hello, jack!

下面是一个例子,可以使用它将一个回调函数绑定到一个对象:

const obj = {
  count: 0,
  increment: function() {
    this.count++;
  }
};

const incrementCount = obj.increment.bind(obj);

incrementCount();
console.log(obj.count);  // 1

bind() 方法将 obj 对象作为第一个参数传递给 increment() 方法,返回一个新函数 incrementCount,其 this 关键字设置为 obj 对象。最后,调用 incrementCount() 函数,该函数会调用 increment() 方法,并将 obj.count 的值自增1

区别及优缺点

call()apply()bind() 方法都可以用于动态设置函数内部的 this 关键字,使函数在不同的上下文中运行。

call()apply() 方法非常相似,它们都立即调用函数,并将函数的 this 关键字设置为传递的对象。不同之处在于,call() 方法的参数是一个一个地传递,而 apply() 方法将参数作为一个数组传递。

bind() 方法不会立即调用函数,而是创建一个新函数,并将函数的 this 关键字设置为传递的对象。它还可以传递一些参数作为默认值。由于 bind() 方法不会立即调用函数,因此它可以方便地用于创建一个新函数,该函数可以稍后调用。

使用这些方法时需要注意的一点是,它们在性能上可能会有所影响。由于这些方法都是动态绑定 this 关键字的,因此它们的执行速度可能会比直接调用函数慢。此外,这些方法会创建新的函数对象,可能会占用更多的内存。

使用场景:

  • 如果有了一个数组,想将其作为一个参数传递给函数,那么使用 apply() 方法。
  • 如果需要动态绑定 this 关键字并立即调用函数,那么使用 call() 方法。
  • 如果需要动态绑定 this 关键字,但是不需要立即调用函数,那么使用 bind() 方法。

总结

call()apply() 方法能够立即调用函数并传递参数,但可能会影响性能;bind() 方法可以动态绑定 this 关键字并创建一个新函数,但不会立即调用函数,可能会占用更多内存,具体可以根据场景选择使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值