javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript this指向

详解JavaScript的三种this指向方法

作者:凌云木丶丶

这篇文章主要介绍JavaScript的三种this指向的方法:call()、bind()、apply(),文中通过代码示例介绍的非常详细,需要的朋友可以参考下

讲一下call()方法

在 JavaScript 中,call() 方法用于调用一个函数,可以指定函数体内 this 对象的值。这里的 this 指的是函数执行时所在的上下文对象,也就是函数执行时所处的环境,同时可以传递参数列表来执行函数。

call() 方法接受的第一个参数是要绑定给 this 的值,后面的参数是传递给函数的参数列表。通过 call() 方法,可以改变函数内部 this 的指向,并且立即执行函数。

以下是 call() 方法的语法:

functionName.call(thisArg, 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() 方法的主要场景包括:

总结:call() 方法用于调用一个函数并设置函数内部的 this 值。它接受一个对象作为 thisArg,将该对象绑定到函数内部的 this 上下文,并可以传递参数列表给函数。这个方法常用于显式设置函数的执行上下文和借用其他对象的方法。

讲一下bind()方法

bind() 方法是 JavaScript 中的一个内置函数,用于创建一个新的函数,这个新函数与原函数绑定了指定的 this 对象和部分参数,并且在调用时这些参数会被预先传入。bind() 方法的语法如下:

functionName.bind(thisArg, arg1, arg2, ...)

bind() 方法会返回一个新的函数,该新函数的 this 值被永久地绑定到 thisArg 所指定的对象。当调用这个新函数时,它会以指定的上下文执行,并将预设的 arg1arg2 等参数预先传入新函数。

使用 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])

参数说明:

使用 apply() 方法可以实现以下功能:

示例:

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 对象,包含 nameage 属性。通过使用 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() 函数,从而得到数组中的最大值和最小值。

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指向的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文