详解JavaScript的三种this指向方法
作者:凌云木丶丶
讲一下call()方法
在 JavaScript 中,call()
方法用于调用一个函数,可以指定函数体内 this
对象的值。这里的 this
指的是函数执行时所在的上下文对象,也就是函数执行时所处的环境,同时可以传递参数列表来执行函数。
call()
方法接受的第一个参数是要绑定给 this
的值,后面的参数是传递给函数的参数列表。通过 call()
方法,可以改变函数内部 this
的指向,并且立即执行函数。
以下是 call()
方法的语法:
functionName.call(thisArg, arg1, arg2, ...)
functionName
:要调用的函数名称。thisArg
:函数执行时绑定的this
值,即函数内部的上下文对象。arg1, arg2, ...
:要传递给函数的参数列表。
当调用 call()
方法时,它会立即执行函数,并将指定的 thisArg
绑定到函数内部的 this
上下文。这意味着函数内部的 this
将引用 thisArg
所指定的对象。
另外,call()
方法还可以接受多个参数作为函数的参数列表,并依次传递给函数。
下面是一个使用 call()
方法的简单例子:
const person = { fullName: function() { return this.firstName + " " + this.lastName; } } const person1 = { firstName: "John", lastName: "Doe" } const person2 = { firstName: "Mary", lastName: "Doe" } // 使用 call() 方法指定 person1 作为函数内部的 this 对象 const fullName1 = person.fullName.call(person1); // 返回 "John Doe" // 使用 call() 方法指定 person2 作为函数内部的 this 对象 const fullName2 = person.fullName.call(person2); // 返回 "Mary Doe"
在上面的例子中,call()
方法被用于在不同的上下文中调用 person.fullName()
函数。通过使用 call()
方法,我们可以指定函数内部 this
的值,并且让函数在不同的上下文中执行,从而达到我们的目的。
使用 call()
方法的主要场景包括:
- 显式设置函数内部的
this
上下文。 - 在借用其他对象的方法时,将当前对象作为
this
上下文。 - 调用函数并传递参数列表。
总结:
call()
方法用于调用一个函数并设置函数内部的this
值。它接受一个对象作为thisArg
,将该对象绑定到函数内部的this
上下文,并可以传递参数列表给函数。这个方法常用于显式设置函数的执行上下文和借用其他对象的方法。
讲一下bind()方法
bind()
方法是 JavaScript 中的一个内置函数,用于创建一个新的函数,这个新函数与原函数绑定了指定的 this
对象和部分参数,并且在调用时这些参数会被预先传入。bind()
方法的语法如下:
functionName.bind(thisArg, arg1, arg2, ...)
functionName
:要绑定上下文的函数名称。thisArg
(必选参数):函数执行时绑定的this
值,即函数内部的上下文对象。arg1, arg2, ...
(可选参数):要预设的参数列表。
bind()
方法会返回一个新的函数,该新函数的 this
值被永久地绑定到 thisArg
所指定的对象。当调用这个新函数时,它会以指定的上下文执行,并将预设的 arg1
、arg2
等参数预先传入新函数。
使用 bind()
方法,可以实现改变函数内部的 this
指向,以及部分参数的预先传入。这个方法在一些特定的场景下非常有用,比如在回调函数中使用,可以解决 this
指向问题。例如:
示例一:
var person = { name: "John", greet: function (message) { console.log(message + ", " + this.name); }, }; var anotherPerson = { name: "Ben", }; var boundGreet = person.greet.bind(person, "Hello"); boundGreet(); // 输出:Hello, John var boundGreet = person.greet.bind(anotherPerson, "Hello"); boundGreet(); // 输出:Hello, Ben
示例二:
const obj = { name: 'Tom', sayHi() { console.log(`Hi, my name is ${this.name}`); }, }; // 在回调函数中使用 bind() 方法改变 sayHi() 函数内部的 this 指向 setTimeout(obj.sayHi(), 1000); // 立即执行 输出:Hi, my name is Tom setTimeout(obj.sayHi.bind(obj), 1000); // 1s后执行 输出:Hi, my name is Tom
上面代码直接用 setTimeout(obj.sayHi(), 1000); 不也可以,为什么还要加上bind()
上面代码直接使用
setTimeout(obj.sayHi(), 1000)
会立即调用obj.sayHi()
函数,并把它的返回值作为第一个参数传递给setTimeout()
函数,相当于setTimeout(undefined, 1000)
。所以实际上是没有等待1秒后再执行sayHi()
的效果的。而
setTimeout(obj.sayHi.bind(obj), 1000)
中,bind()
方法会返回一个绑定了obj
作为上下文的新函数,并不会立即调用。所以setTimeout()
函数会等待1秒后再调用这个新函数,保证了1秒后再执行sayHi()
函数。
又例如,预先传入部分参数的情况:
function add(x, y) { return x + y; } // 使用 bind() 方法预先传入参数 1,得到一个新的函数 const addOne = add.bind(null, 1); console.log(addOne(2)); // 输出:3
在上面的例子中,使用 bind()
方法预先传入了参数 1
,得到一个新的函数 addOne
,在调用这个新函数时,只需要再传入一个参数 2
,即可完成 1 + 2
的操作。
讲一下apply方法
apply()
方法是 JavaScript 中的一个函数方法,用于在特定的作用域中调用函数,并将参数以数组形式传递。
语法:
function.apply(thisArg, [argsArray])
参数说明:
thisArg
:可选参数,指定函数执行时的作用域对象。在函数内部使用this
关键字时,将引用该参数指定的对象。如果省略或传入null
或undefined
,则在调用时使用全局对象(通常是window
对象)作为作用域。argsArray
:可选参数,一个数组或类数组对象,包含传递给函数的参数。如果省略或传入null
或undefined
,则表示不传递任何参数。
使用 apply()
方法可以实现以下功能:
- 在特定作用域中调用函数:通过指定
thisArg
参数,可以在特定对象的作用域中执行函数,修改函数内部的this
引用。 - 传递参数数组:将参数以数组形式传递给函数,可以方便地在调用函数时动态传递参数。
示例:
function greet(name, age) { console.log(`Hello, ${name}! You are ${age} years old.`); } const person = { name: 'Alice', age: 25 }; greet.apply(person, ['Bob', 30]); // 输出:Hello, Bob! You are 30 years old. // 相当于在person对象作用域里面打印了 "Hello, Bob! You are 30 years old." 打招呼的话
在上面的示例中,我们定义了一个 greet
函数用于打招呼,接受一个 name
参数和一个 age
参数。然后,我们创建了一个 person
对象,包含 name
和 age
属性。通过使用 apply()
方法,我们将 person
对象作为函数调用的作用域,并传递一个包含 'Bob'
和 30
的参数数组。最终,函数在 person
对象的作用域中执行,并输出相应的结果。
apply和call的区别
需要注意的是,apply()
方法和 call()
方法的作用类似,唯一的区别是参数的传递方式不同。apply()
方法使用数组形式传递参数,而 call()
方法使用逐个参数传递。
apply()其他应用场景
当使用 apply()
方法时,还可以在某些情况下提供更灵活和动态的函数调用。以下是一些使用 apply()
方法的其他例子:
动态改变函数的上下文:
function greet() { console.log(`Hello, ${this.name}!`); } const person1 = { name: 'Alice' }; const person2 = { name: 'Bob' }; greet.apply(person1); // 输出:Hello, Alice! greet.apply(person2); // 输出:Hello, Bob!
通过使用 apply()
方法,可以动态地将不同的对象作为函数调用的上下文(this
)。
数组操作:
const numbers = [1, 2, 3, 4, 5]; const max = Math.max.apply(null, numbers); const min = Math.min.apply(null, numbers); // const max = Math.max(...numbers); // const min = Math.min(...numbers); console.log(max); // 输出:5 console.log(min); // 输出:1
在这个例子中,通过使用 apply()
方法,将数组作为参数传给 Math.max()
和 Math.min()
函数,从而得到数组中的最大值和最小值。
配合
arguments
对象使用:
function sum() { // 将 arguments 对象转换为真正的数组 const argsArray = Array.prototype.slice.call(arguments); // 使用 reduce 方法对数组中的元素进行累加求和,初始值为 0 return argsArray.reduce((total, num) => total + num, 0); // 这里传入的实参0是可选参数initialValue,用于指定累积的初始值 // 如果没有提供初始值,则将使用数组的第一个元素作为初始值,并从第二个元素开始进行迭代。 // 所以不写也是OK的,结果相同 } const numbers = [1, 2, 3, 4, 5]; // 使用 apply 方法将 numbers 数组作为参数传递给 sum 函数,并执行求和操作 const result = sum.apply(null, numbers); console.log(result); // 输出:15
在这个例子中,sum()
函数接收任意数量的参数,并使用 apply()
方法将参数数组传递给函数。通过将 arguments
对象转换为真正的数组,我们可以对参数进行操作,例如在此例中计算它们的总和。
总之,apply()
方法提供了一种动态调用函数的方式,并且在某些情况下非常有用,特别是在需要改变函数上下文、操作数组或处理不定数量的参数时。
以上就是详解JavaScript的三种this指向方法的详细内容,更多关于JavaScript this指向的资料请关注脚本之家其它相关文章!