JavaScript中this指向详解:五种常见场景与代码实例
本文详细解析JavaScript中this关键字的取值规则。通过全局环境、普通函数调用、构造函数、对象方法、原型链以及call/apply五种场景的代码实例,阐明this在运行时动态确定的特性,帮助开发者准确理解并避免常见陷阱。
JavaScript this指向详解:五种常见场景与代码实例
本文通过具体实例,深入探讨JavaScript中this关键字的核心机制,旨在帮助读者清晰理解其工作原理,供学习参考。
执行上下文与this的确定时机
函数内部this的具体指向,并非在定义时确定,而是取决于函数被调用执行时的实际上下文环境。
执行上下文环境:
**定义**:函数执行时会创建一个执行上下文对象,该对象存储了当前运行所需的变量、函数声明以及this的值。
**作用**:用于保存本次函数运行期间所需的所有数据状态。
当代码中使用this时,解释器会直接从当前的执行上下文中获取其值,而不会去作用域链中查找。
this指向的五大场景分析
关于this的取值规则,主要可以归纳为以下几种常见情况:
全局环境与普通函数调用
情况一:全局环境与普通函数调用
在全局执行环境中,this始终指向window对象。
console.log(this === window); //true
当普通函数被直接调用时(注意:此处指非构造函数模式,即未使用new关键字),其内部的this同样指向window。
然而,若在全局严格模式下调用该函数,则会抛出错误:
var x = 1;
function first(){
console.log(this); // undefined
console.log(this.x); // Uncaught TypeError: Cannot read property 'x' of undefined
}
first();
构造函数模式下的this
情况二:构造函数模式
所谓构造函数,是指通过new关键字实例化对象的函数。通常构造函数的命名规范为首字母大写,例如Object、Function、Array等内置构造函数均符合此特征。
function First(){
this.x = 1;
console.log(this); //First {x:1}
}
var first = new First();
console.log(first.x); //1
在上述代码中,当函数作为构造函数使用时,其内部的this指向即将通过new创建的新对象实例。
但如果直接调用First函数(即不使用new First()),则其行为回归到情况一,此时First()被视为普通函数调用。
function First(){
this.x =1;
console.log(this); //Window
}
var first = First();
console.log(first.x); //undefined
对象方法中的this行为
情况三:对象方法调用
当函数被作为对象的方法调用时,方法内部的this指向该方法所属的对象。
var obj = {
x: 1,
first: function () {
console.log(this); //Object
console.log(this.x); //1
}
};
obj.first();
需要注意的是,如果在对象方法内部定义并调用另一个函数,情况将发生变化。
var obj = {
x: 1,
first: function () {
function second(){
console.log(this); //Window
console.log(this.x); //undefined
}
second();
}
}
obj.first();
可以这样理解:函数second虽然在obj.first内部定义,但它本质上仍是一个普通函数,因此其this依然指向window。
在此场景下,若需访问外层作用域中的变量obj.x,可采用self变量缓存外部this的方式来解决。
var obj = {
x:1,
first: function () {
var self = this;
function second(){
console.log(self); //{x: 1}
console.log(self.x); //1
}
second();
}
}
obj.first();
如果first函数并未作为对象方法被调用:
var obj = {
x: 1,
first: function () {
console.log(this); //Window
console.log(this.x); //undefined
}
};
var fn = obj.first;
fn();
当obj.first被赋值给一个全局变量,且未作为obj的属性直接调用时,此时的this值为window。
原型链与call方法的影响
情况四:构造函数prototype属性
function First(){
this.x = 1;
}
First.prototype.getX = function () {
console.log(this); //First {x: 1, getX: function}
console.log(this.x); //1
}
var first= new First();
first.getX();
在First.prototype.getX函数中,this指向的是first实例对象。不仅如此,在整个原型链中,this始终代表当前调用该方法的对象值。
情况五:使用call方法调用函数
var obj = {
x:1
}
function first(){
console.log(this); //{x: 1}
console.log(this.x); //1
}
first.call(obj);
当函数通过call方法被调用时,this的值将被显式指定为传入的第一个参数对象的值。
来源:知乎
链接:https://zhuanlan.zhihu.com/p/25294187?utm_source=com.youdao.note&utm_medium=social
感兴趣的朋友可以使用在线HTML/CSS/JavaScript前端代码调试运行工具:http://tools.jb51.net/code/WebCodeRun测试上述代码运行效果。
更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
