call()和apply()区别

167 阅读2分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

call()和apply()

在javaScript中,每个函数的对象实例都有call()、aplly()属性,call()、aplly()也是都属于Funtion.prototype的一个方法;在代码中,call()和apply()的作用是一样的,都是为了改变执行上下文,也就是传说中函数里面的this指向,只是使用的方式不太一样。

传参的方式不同

  • call()传进去的参数第一个是this,后面的参数可以是多个,相当于一个列表,然后一个一个传进去
  • apply()传进去的参数最多只能有两个,第一个是this,第二个是一个数组或者类数组arguments;如果需要传递多个参数,那就把这些参数写成一个数组的形式,即使只有一个参数也必须写成数组的形式,再传进去;若是第二个数组传进去的不是数组或者类数组,将直接抛出错误。
  • call()和apply()中的第一个参数this是一样的,只是第二个参数的传入方式不太一样:call(this, name, age, sex),而apply(this, [a, b, c, d])。
function Person(name, age) {
  this.name = name,
  this.age = age,
  this.sayHi = function(name) {
    console.log(`${this.name}今年${this.age}岁`);
  }
}
function Student(name,age) {
  Person.call(this, name, age)
}
function Student1(arguments) {
  Person.apply(this, arguments)
}
let xiaomin = new Student('小明',12);
let xiaohong = new Student1(['小红',14]);
xiaomin.sayHi(); // 小明今年12岁
xiaohong.sayHi();// 小红今年14岁

如上所示,分别声明了构造函数Person,Student;Person里有属性和方法,Student则不给任何东西,但我们需要从Student new一个新的实例出来用,但是现在它又没有任何属性方法,咋整呢?这里就可以用call或者aplly方法从别的函数对象中复制获取到;在函数Student中,使用Person.call(this, name)或者Person.apply(this, arguments)改写this指向,都将this指向Person,并且继承了Person的属性和方法;这里不能将Person.apply(this, arguments)里面的参数改成Person.apply(this, name),无论你的参数是只有一个还是有很多个,统统都必须写成一个数组,否则会直接报这个错“Uncaught TypeError: CreateListFromArrayLike called on non-object”。