zoukankan      html  css  js  c++  java
  • JavaScript中this指向问题

    JavaScript中this指向问题

    记得初学 JavaScript 时,其中 this 的指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称 JS 武林中的三大魔头。如果你要想在 JS 武林中称霸一方,必须将这三大魔头击倒。个人认为在这三大魔头中,this 指向问题的武功最菜(难度最低)。俗话说柿子捡软的捏,那我们就先从 this 指向问题下手。

    先记住攻克 this 指向问题的口诀(前辈们的总结):哪个对象调用函数,函数里的 this 就默认指向哪个对象(注意 this 只能指向对象)。这里说“默认指向”是因为我们通过箭头函数、call、apply、bind等手段来改变 this 的指向。现在我们只讨论 this 的默认指向。

    全局作用域下以及全局作用域的函数中,this默认指向全局对象window

    在严格模式下,全局作用域的函数中,this默认指向 undefined, 这是严格模式所规定的。

    // 非严格模式下
    console.log(this); // Window
    function doSomething(){
        console.log(this); // Window
    }
    doSomething(); // 这里可以看成window.doSomething(),所以函数里的this指向全局对象window
    // 严格模式下
    'use strict';
    console.log(this); // Window
    function doInStrict(){
        console.log(this); // undefined
    }
    doInStrict();
    

    对象里的函数,this指向该对象

    var a = 1;
    var obj = {
        a: 2,
        fn: function(){
            console.log(this); // {a: 2, fn: ƒ}
            console.log(this.a); // 2
        }
    };
    obj.fn();
    

    上面函数被调用后,从打印结果可以看出此时 this 指向的是调用函数的对象 obj。如果将对象中的函数赋给全局对象中定义的变量 fn1,执行 fn1 又会出现什么结果呢?

    var a = 1;
    var obj = {
        a: 2,
        fn: function(){
            console.log(this); // Winidow
            console.log(this.a); // 1
        }
    };
    var fn1 = obj.fn;
    fn1(); // 可以看成window.fn1();
    

    从上面的例子可以看出,fn1 与 obj.fn 指向的函数是相同的,但是调用它的对象不同,那么函数中 this 的指向也就不一样了。

    再看一个比较复杂的例子:

    var a = 0;
    function fn(){
    	consoloe.log(this.a);
    }
    var obj1 = {
    	a: 1,
    	fn: function(){
    		console.log(this.a);
    	}
    };
    var obj2 = {
    	a: 2,
    	fn: function(){
    		fn();
    		obj1.fn();
    		console.log(this.a);
    	}
    }
    obj2.fn();
    

    先说下执行结果,分别打印 0 1 2。当 obj2 调用 fn 函数时,先执行的是 fn(),这个函数是在全局作用域中定义的,该调用可以看成 window.fn(),所以,该函数内部的 this 指向的是 window 全局对象,this.a 自然就是全局对象中的 a 值(0)。

    接着执行的是 obj1.fn(),它会从 obj1 中找到 fn 函数并执行。obj1 中的函数 fn 执行时调用它的对象是 obj1,所以,此时函数内部的 this 指向的就是 obj1 自身。那么 this.a 查到的值也就是对象 obj1 中 a 的值(1)。

    最后打印函数中 this 所处的函数 fn 是被 obj2 调用的,那么自然而然 this 就指向了 obj2,所以 this.a 的结果就是 2 了。

    从上面这个例子我们可以看出:函数内部 this 指向跟调用函数的对象有关,跟函数在哪里调用没有关系。

    Window内置函数的回调函数中,this指向Window对象。

    window 的内置函数( setInterval setTimeout 等),其回调函数中的 this 指向的是window对象。

    var name = 'window';
    var obj = {
        name: 'obj',
        func: function(){
            setTimeout(function () {
                console.log(this.name) // window
            },1000)
        }
    }
    
    obj.func()
    

    但是一般在开发中,很多场景都需要改变 this 的指向。 请参考JS中this指向的更改,这里就不再赘述了。
    this 既不指向函数自身也不指向函数的词法作用域,this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
    找到函数直接调用的位置后用下面的几条规则就可以判断出 this 的绑定对象。

    1. 由 new 调用?绑定到新创建的实例对象上。
    2. 由 call、apply、bind调用?绑定到指定的对象上。
    3. 由上下文对象调用?绑定到那个上下文对象上。
    4. 默认:在严格模式下绑定到 undefined,否则绑定到全局对象 Window 上。
    5. ES6 中的箭头函数会继承外层函数调用的 this 绑定,这和 var self = this;的绑定机制一样。
  • 相关阅读:
    9.5(day3)
    9.4(day2)
    web第一阶段 9.3(day1)
    8.29
    8.28
    8.27
    8.24
    dockerfile的编写
    深入解析pod对象的基本概念
    k8s最小调度pod的概念
  • 原文地址:https://www.cnblogs.com/laozhenHome/p/13262592.html
Copyright © 2011-2022 走看看