不是我,你是谁?搞懂JavaScript中的this指向!
JavaScript中的this指向:从原型对象的疑惑谈起
在深入探讨JavaScript中this关键字的奥秘之前,让我们先从JavaScript的核心概念之一——原型对象谈起。当我学习原型对象的机制时,里面的this让我觉得难以捉摸,因为它直接影响着函数执行时上下文环境的构。为了彻底弄懂this到底指向的是谁,我们从原型对象的例子开始说起。
原型对象基础
在JavaScript中,每个函数都有一个内置的属性叫做prototype,这个属性是一个对象,也就是常说的原型对象。原型对象的主要作用是实现继承机制,允许对象共享属性和方法。当一个对象需要访问一个自身没有但存在于其原型链上的属性或方法时,JavaScript引擎会自动向上查找,直至原型链的顶端。
我们看一下这个例子就明白了:
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
console.log(this.name + '吃的正爽');
};
let dog = new Animal('moni');
dog.eat(); // moni吃的正爽
在这个例子中,eat
方法定义在Animal.prototype
上,所有由Animal
构造函数创建的实例都能访问到这个方法,这是因为在这些实例的原型链上指向了Animal.prototype
。当dog
这一实例被new
出来并调用了eat
方法时,这里的this也就指向了dog
。
引出this的指向
this关键字在JavaScript中是一个非常灵活的内容,其指向取决于函数调用的上下文。理解this的指向对于正确编写代码至关重要。让我们结合原型对象的概念,通过几个典型场景来深入解析this的指向。
1. 构造函数中的this
在构造函数中,this指向新创建的对象实例。
function Person(name) {
this.name = name;
this.say = function() {
console.log(this.name + '正在发言');
};
}
let tom = new Person('Tom');
tom.say(); // Tom正在发言
在这个例子中,this在构造函数内部指向新创建的tom
实例,因此name
属性被赋予了实例为Tom
,并且say
方法中的this也指向该实例。这与开头提到的例子是差不多的,但this的指向却远不止这些。
2. 方法调用中的this
当对象的方法被调用时,this指向该方法所属的对象。
let pet = {
name: 'moni',
shout: function() {
console.log(this.name + '正在大喊大叫');
}
};
pet.shout(); // moni正在大喊大叫
这里的shout
方法内的this指向pet
对象,因此才能正确得到到name
属性。
3. 箭头函数中的this
箭头函数不绑定自己的this,它会捕获其所在上下文的this值。
const person = {
name: '小小',
say: () => {
console.log(`大家好,我是 ${this.name}`); // 这里的this并不指向person
}
};
person.say(); // 大家好, 我是 undefined 因为箭头函数没有自己的this
箭头函数不会像普通函数那样根据调用方式改变this的值,它总是指向定义时的上下文环境,在这个例子中,由于是在全局作用域中声明,所以this指向全局对象,找不到就输出undefined
。
4. 显式绑定this
使用
.call()
,.apply()
, 或者.bind()
方法都可以显式地设置函数中的this值。
function greet(content) {
console.log(content + ', ' + this.name);
}
let person = {
name: '李白'
};
greet.call(person, '你好'); // 你好,李白
通过.call()
,我们将greet
函数的this
绑定到了user2
对象,从而访问到了name
属性。
总结
this的指向是JavaScript中一个复杂而重要的概念,它依赖于函数的调用上下文。在不同情况下this的指向规则也是随之改变的,将其牢牢记住,是深入JavaScript编程的关键。通过以上的那些例子,我们可以看到this的指向既受到函数调用方式的影响,也受到语言特性的约束。熟练掌握this的使用,才能够让我们更加灵活地编程。
希望这些内容能够让你对this有更深地理解,一起加油!
转载自:https://juejin.cn/post/7375183112837267466