JavaScript 的 this指向 通俗易懂

1,145 阅读3分钟

this是什么?

this 是由 JavaScript 引擎在执行函数时自动生成的,存在于函数内的一个动态指针,指代当前调用对象。在英文翻译中,this的意思为“这个;当前”,是一个指针型变量,它动态指向当前函数的运行环境。在不同的场景中调用同一个函数,this的指向也可能会发生变化, 但是它永远指向其所在函数的真实调用者;如果没有调用者,就指向全局对象window。

这里我直接通过两个例子来帮大家区分两种情况的this指向,首先大家可以把指向理解为等于,这样就好理解了。

    const name = "怪兽";
    
    function fun() {
       console.log(this.name);  // 怪兽
    }
    fun(); 

    let obj = {
        name: "奥特曼",
        fn: fun,
    };
    
    obj.fn(); //奥特曼
    

上图中一个是用函数调用的this指向,一个是用对象调用的this指向,大家通过查看结果可以清楚的看到函数指向的是window,对象里的函数指向的是对象的属性。这也就是为什么很多代码里面,有人用var that = this 的原因,因为有的时候函数里面的this不是你要想的this。

改变this指向的方法

call()方法

1.可直接调用函数

2.括号里可传值,第一个值写要改变的this指向的位置,后面可以写入要传入的参数

3.可实现继承

    const name = "怪兽";
    function fun() {
       console.log(this.name);  
    }
    fun(); 

    let obj = {
        name: "奥特曼",
        fn: fun,
    };
    obj.fn(); //奥特曼
    fun.call(obj)

上图中第一次调用函数fun 打印的结果是怪兽 ,第二次是Obj.fun()打印结果是奥特曼,第三次fun.call(obj) 是奥特曼,这说明call()成功改变了fun的函数指向,若不改变this指向,fun本身指向的是window,而call()方法改变了this指向,使其指向了obj对象。

// 实现继承
function Man(uname,uage,usex) {
    this.uname = uname;
    this.uage = uage;
    this.usex = usex;
}
function Person(uname,uage,usex) {
    Man.call(this,uname,uage,usex)
}
var person = new Person('NiKO',18,'男')
console.log(person);

上图中将人类的属性"名字","年龄","性别",传递给了男人,这种写法让Man继承了Person的属性。

apply()方法

1.也是调用函数,改变this指向与call()方法同。

2.而括号内传入参数必须是数组,这是与call()方法不同之处。

3.apply的主要应用,比如可以利用apply借助于数学内置对象求最大值。Math.max()

function u(arr) {
    console.log(this)  //{name:Helen}
    console.log(arr) // 4
}
var h = {
    name: 'Helen'
}
u.apply(h,[4])

bind()方法

1.与call(),apply()区别,不会调用原来函数,若想调用需要赋值后再调用一遍,调用函数与call()同。

2.bind()在这三个方法中用的最多。

3.如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向,此时用bind。

// bind方法
// 与call(),apply()区别,不会调用原来函数,需要赋值后再调用一遍,调用函数与call()同
function f(a,b) {
    console.log(this)
    console.log(a - b)
}
var j = {
    name: 'Kuper'
}
var h = f.bind(j,6,1);
h();

第三种情况的例子

var btn = document.querySelector('button');
    btn.addEventListener('click',function () {
        this.disabled = true;  // 这个this指向的是btn这个按钮
        setTimeout(function () {
            this.disabled = false; //this本身在定时器里指向的是window,通过bind()方法改变了this指向
        }.bind(this),3000) // 这个this指向的是btn这个对象。因为这个this是在定时器外边而在btn这个对象