欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Javascript函数内置方法call/apply实例讲解

程序员文章站 2022-06-20 23:52:52
javascript默认为每个函数提供了call()和apply()用来设置函数的上下文对象 call() call()方法的具体语法内容如下: func.call(co...

javascript默认为每个函数提供了call()和apply()用来设置函数的上下文对象

call()

call()方法的具体语法内容如下:

func.call(context, arg1, arg2, ...)

其中context是上下文对象;arg1,arg2,...是函数func的参数,以列表的形式接受

这里是一个例子:

function say(phrase) {
  alert(this.name + ': ' + phrase);
}

let user = { name: "john" };
let admin = { name: "admin" };

// user becomes this, and "hello" becomes the first argument
say.call( user, "hello" ); // john: hello
say.call( admin, "hello" ); // admin: hello

此时因为call()传递给say()的上下文对象为user或者admin,故say()中的this所指向的上下文对象就为user或admin

apply()

apply()的用法和call()很像,具体语法如下:

func.apply(context, args)
与call()不同的是,apply()的第二个参数args接受的是函数参数所组成的数组,看下面例子:
function say(time, phrase) {
  alert(`[${time}] ${this.name}: ${phrase}`);
}

let user = { name: "john" };

let messagedata = ['10:00', 'hello']; // become time and phrase

// user becomes this, messagedata is passed as a list of arguments (time, phrase)
say.apply(user, messagedata); // [10:00] john: hello (this=user)

apply()和call()不同的是,call()接受的是函数参数的列表,而apply()接受的是函数参数的数组形式,如下:

let args = [1, 2, 3];

func.call(context, ...args); // pass an array as list with spread operator
func.apply(context, args);   // is same as using apply

上面例子的最终效果是一样的,我们已经知道rest参数的拓展操作可以将数组等可迭代对象转换为列表,故这里使用...args来进行转换args数组

借用别的对象的方法

call()和apply()除了设置上下文对象外,还可以用来调用其他对象的方法,先看下面例子:

function hash() {
  alert( arguments.join() ); // error: arguments.join is not a function
}

hash(1, 2);

这里arguments.join()报错了,因为arguments参数是函数的默认内置参数,其中包含了函数的所有输入参数,然而它是类数组和可迭代的对象,不是真正的数组对象,故使用jion()这个数组专有的方法就会报错(join()以字符串的形式返回数组的内容)。为了解决这个问题,我们可以使用call()或者apply()来借用数组对象的方法,例如:

function hash() {
  alert( [].join.call(arguments) ); // 1,2
}

hash(1, 2);

这里join()的上下文对象被设置为arguments,join()内部原理是迭代数组对象每一个元素并将元素内容拼接到一个字符串中,再返回,所以[].join.call(arguments)可以正常工作