答题思路
- 解释
this关键字的基本概念 :先说明this关键字在 JavaScript 中是一个特殊的存在,它的值不是固定的,会根据函数的调用方式和上下文环境而变化。 - 列举不同的场景 :分别阐述在函数调用、方法调用、构造函数调用、箭头函数以及使用
call、apply、bind方法等场景下this的取值情况。对于每个场景,先描述场景的特点,再说明this是如何取值的,并通过代码示例来辅助理解。 - 总结归纳 :对不同场景下
this的取值进行总结,帮助加深记忆和理解。
回答范文
在 JavaScript 里,this 关键字是个很重要但又有点让人头疼的东西,因为它的值不是固定不变的,会跟着函数的调用方式和环境变来变去。下面咱们就来看看在不同场景下它都是怎么取值的。
1. 函数调用场景
javascript
// 定义一个普通函数
function sayHello() {
// 在函数内部使用 this 关键字
console.log(this);
}
// 直接调用函数
sayHello();
解释 :在这种普通函数直接调用的情况下,this 的值在非严格模式下会指向全局对象(在浏览器环境中是 window 对象),在严格模式下会是 undefined。比如上面代码在非严格模式下运行,会打印出 window 对象;如果在严格模式下(在函数内部第一行加上 'use strict';),就会打印出 undefined。
2. 方法调用场景
javascript
// 创建一个对象
const person = {
name: '小明',
// 在对象中定义一个方法
sayHi: function() {
// 在方法内部使用 this 关键字
console.log(this.name);
}
};
// 调用对象的方法
person.sayHi();
解释 :当函数作为对象的方法被调用时,this 会指向这个对象本身。在上面的例子中,sayHi 方法是 person 对象的方法,所以调用 person.sayHi() 时,this 就指向 person 对象,从而可以访问到 person 对象的 name 属性,打印出 小明。
3. 构造函数调用场景
javascript
// 定义一个构造函数
function Person(name) {
// 在构造函数内部使用 this 关键字来定义对象的属性
this.name = name;
}
// 使用 new 关键字调用构造函数创建对象
const newPerson = new Person('小红');
// 打印新创建对象的 name 属性
console.log(newPerson.name);
解释 :当使用 new 关键字调用构造函数时,this 会指向新创建的对象实例。在 Person 构造函数中,this.name = name; 就是把传入的参数 name 赋值给新创建对象的 name 属性。所以最后创建出来的 newPerson 对象的 name 属性就是 小红。
4. 箭头函数场景
javascript
// 创建一个对象
const user = {
name: '小李',
// 在对象中定义一个箭头函数
saySomething: () => {
// 在箭头函数内部使用 this 关键字
console.log(this.name);
}
};
// 调用对象的箭头函数
user.saySomething();
解释 :箭头函数没有自己的 this 值,它的 this 是继承自外层作用域(也就是定义箭头函数的地方)。在上面例子中,箭头函数 saySomething 的 this 指向的是全局对象(在浏览器环境中是 window,因为这里没有可继承的合适对象),而全局对象一般没有 name 属性,所以可能会打印出 undefined。
5. 使用 call、apply、bind 方法场景
javascript
// 定义一个函数
function introduce() {
console.log(this.name);
}
// 创建一个对象
const anotherPerson = {
name: '小张'
};
// 使用 call 方法调用函数,并指定 this 的值为 anotherPerson 对象
introduce.call(anotherPerson);
// 使用 apply 方法调用函数,并指定 this 的值为 anotherPerson 对象
introduce.apply(anotherPerson);
// 使用 bind 方法创建一个新的函数,并指定 this 的值为 anotherPerson 对象
const newIntroduce = introduce.bind(anotherPerson);
// 调用新创建的函数
newIntroduce();
解释 :call 和 apply 方法可以改变函数调用时 this 的指向,它们的第一个参数就是要指定的 this 值。call 方法后面跟的是一个个具体的参数,apply 方法后面跟的是一个参数数组。bind 方法会返回一个新的函数,这个新函数的 this 被固定为 bind 方法指定的值,所以调用新函数时,this 就会指向指定的对象,上面例子中就是 anotherPerson 对象,从而能打印出 小张。
总结一下,this 关键字的值在不同场景下变化很大,函数调用、方法调用、构造函数调用、箭头函数以及 call、apply、bind 方法等场景下,this 会有不同的取值。理解这些场景和 this 的取值规则,对写好 JavaScript 代码很重要哦。
上述提到的方法this关键字是如何取值的
上述提到的方法中,this关键字的取值情况如下:
-
函数调用场景
- 非严格模式 :
this指向全局对象,在浏览器环境中是window对象。比如在一个普通函数内部,如果没有使用严格模式,console.log(this)会打印出window对象。 - 严格模式 :
this的值为undefined。在函数内部第一行加上'use strict';开启严格模式后,console.log(this)会打印出undefined。
- 非严格模式 :
-
方法调用场景 :当函数作为对象的方法被调用时,
this指向调用该方法的对象本身。例如obj.method(),method函数中的this就指向obj。 -
构造函数调用场景 :使用
new关键字调用构造函数时,this指向新创建的对象实例。在构造函数内部可以通过this来定义和初始化新对象的属性和方法。 -
箭头函数场景 :箭头函数没有自己独立的
this,它的this继承自外层作用域,即定义箭头函数的地方。如果在全局环境中定义箭头函数,那么它的this通常指向全局对象;如果在某个函数内部定义箭头函数,它的this就继承自该函数的this。 -
call、apply、bind方法场景call方法 :call方法的第一个参数就是要指定的this值,后面可以跟多个参数,作为函数的参数传入。通过call调用函数时,函数内部的this就会指向传入的第一个参数对象。apply方法 :与call方法类似,第一个参数也是指定的this值,但第二个参数是一个数组,数组中的元素作为函数的参数传入。函数内部的this同样指向传入的第一个参数对象。bind方法 :bind方法会返回一个新的函数,这个新函数的this被固定为bind方法指定的值。在调用新函数时,this就会始终指向绑定的对象。