答题思路
- 解释
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
就会始终指向绑定的对象。