javascript this的指向

全局环境 this

在全局执行环境中,this都指向浏览器的window

console.log(this === window); // true 
this.name = 'window的name';
console.log(window.name); // window的name

普通函数 this

普通函数被直接调用时,this都指向浏览器的window,不限嵌套层数

function outFn() {
    console.log('outFn', this, this === window);
    function innerFn() {
        console.log('innerFn', this, this === window);
    }
    innerFn();
}
outFn();

// 打印结果:
// outFn window {……} true
// innerFn window {……} true

构造函数 this

在构造函数内部环境中,this都指向实例对象

function Fn(name) {
    this.name = name;
    this.getName = function () {
        console.log(`实例对象${this.name}:`, this);
    }
}

const obj = new Fn('obj');
const arr = new Fn('arr');
obj.getName();
arr.getName();
// 打印结果:
// 实例对象obj: Fn {name:'obj', ……}
// 实例对象arr: Fn {name:'arr', ……}

对象属性 this

当函数为一个对象的属性时,this指向调用该函数的 最近对象

const obj = {
    name: 'obj',
    getName: function () {
        console.log('this:', this);
        console.log('this指向obj?', this === obj);
    }
}
obj.getName();
// 打印结果:
// this: {name: 'obj', getName: f}
// this指向obj? true

// 为obj对象增加一个子属性child
obj.child = {
    childName: 'obj.child',
    getChildName: function () {
        console.log('this:', this);
        console.log('this指向obj?', this === obj);
        console.log('this指向obj.child?', this === obj.child);
    }
};
obj.child.getChildName();
// 打印结果:
// this: {childName: 'obj.child'', getChildName : f}
// this指向obj? false
// this指向obj.child? true

事件绑定 this

通过js进行事件绑定的函数,this指向触发事件的dom元素

<button id='btn'>按钮</button>
function Fn(e) {
    console.log('this:', this);
    console.log('this === e.currentTarget', this === e.currentTarget);
}

const btn = document.getElementById('btn'); // 假设有一个button按钮,id为btn

btn.addEventListener('click', Fn, false); // 绑定click事件

// 点击button后,打印结果:
// this:<button id='btn'>按钮</button>
// this === e.currentTarget true

作为一个内联事件时,当在函数外层的this时,指向触发事件的dom元素,当在函数内部时,则跟普通函数一样,指向window

<!-- 函数外层 -->
<button onclick='console.log("按钮1",this)'>按钮1</button>
<!-- 函数内部 -->
<button onclick="fn()">按钮2</button>
<!-- 函数内部 -->
<button onclick='(function(){console.log("按钮3",this)})()'>按钮3</button>
function fn() {
    console.log('按钮2:', this);
}

// 分别点击按钮1、2后,打印结果:
// 按钮1 <button οnclick='console.log("按钮1",this)'>按钮1</button>
// 按钮2 window {……} 
// 按钮3 window {……} 

Class类 this

Class类中的this指向实例对象,而静态函数中的this则指向class本身。

class Person {
    constructor(name, old) {
        this.name = name;
        this.old = old;
        console.log(`${this.name}的年龄是${this.old}`);
    }
    getThis() {
        return this;
    }
}
const Lee = new Person('李', 20);
const Su = new Person('苏', 18);
console.log('Lee的this:', Lee.getThis());
console.log('Su的this:', Su.getThis());
// 打印结果:
// 李的年龄是20
// 苏的年龄是18
// Lee的this: Person {name:'李', old: 20, __proto__: Object}
// Su的this: Person {name:'苏', old: 18, __proto__: Object}

细心的童鞋估计发现了一个现象,为什么打印出来this的值,没有constructorgetThis的函数的?点开__proto__后如下:

// Su的this值: 
{
    name: '苏',
    old: 18,
    __proto__: {
        constructor: class Person,
		getThis: f getThis(),
        __proto: Object
    }
}

有些了解过原型链的童鞋估计觉得上面很眼熟了。
由于class类,也是基于原型和原型链做的,所以简单的class也可以等于:

function Person(name, old){
   this.name = name;
   this.old = old;
}
Person.prototype.getThis = function () {
   return this;
}
const Su = new Person('苏', 18);
console.log('Su:', Su); // 打印结果可以尝试一下看看,跟上面的是一样的。

不过class也有一点不同的,就是class存在静态函数。函数内的this指向的是class本身。

class Person{
   static getThis(){
   		return this;
   }
}
console.log('class静态函数的this:',Person.getThis());
// 打印结果:
// class Person……

PS:
关于原型链可以参考:《javascript 原型和原型链》
关于如何改变this指向可以参考:《javascript 关于bind、apply、call函数改变this指向》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值