深入理解JavaScript this

this的指向與面向對象是JS一個繞不開的話題,在面試的過程中也經理被問到,我們通過不同的場景來分析this的指向問題,讓我們來更好的瞭解JS中的this.

this在不同調用環境的指向

全局環境

  1. 瀏覽器 -> window
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this Demo</title>
</head>
<body>
<script>
    console.log(this);
</script>
</body>
</html>

這段代碼this輸出的是window對象。

  1. node環境 -> module.exports
//this.js
console.log(this);
console.log(this === module.exports);

在node環境下執行 node this.js 輸出 {}, node環境下this 爲module.exports。

函數內部

  1. this最終指向調用它的對象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this Demo</title>
    <style>
        .box ,.box2{
            width: 80px;
            height: 80px;
            background-color: aquamarine;
            position: relative;
            left: 0;
            transition: 1s;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <div style="margin-top: 10px;" class="box2"></div>
<script>

    function move() {
        this.style.left = '120px';
    }
    let box = document.querySelector('.box');
    box.onclick = move;
    let box2 = document.querySelector('.box2')
    box2.onclick = move;
</script>

</body>
</html>

box點擊指向box,box2點擊就指向box2.

  1. 默認情況下,沒有直接調用者,this指向window
    這個和全局下的是一樣的指向window.

  2. 函數被多層對象包含,this指向上一級的對象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this Demo</title>
    <style>
        .box ,.box2{
            width: 80px;
            height: 80px;
            background-color: aquamarine;
            position: relative;
            left: 0;
            transition: 1s;
        }
    </style>
</head>
<body>
<script>

    let obj = {
        a: 1,
        fn: function () {
            console.log(this);
        }
    }
    obj.fn();
    //var myFunc = obj.fn;
    //myFunc();
    //window.myFunc();
</script>

</body>
</html>

這裏的this指向了 obj這個對象。

  1. 嚴格模式下(設置了’use strict’),this爲undefined
  2. 構造函數的指向
    構造函數中如果有return, return返回的值是對象,this指向返回的對象,如果返回的不是對象,指向的是創建的實例對象
    null比較特殊
    let person = new Person(30); 通過new創建的實例對象經過的幾個步驟
    • 調用函數
    • 自動創建一個對象
    • 把創建出來的實例和this進行綁定
    • 如果構造函數沒有返回值,默認返回this對象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function Person() {
        this.age = 18;

        // return {
        //     age : 88
        // }
    }

    Person.age = 28;
    Person.prototype.age = 38;

    Person.prototype.getAge = function () {
        console.log(this.age);
    }

    let prototype = Person.prototype;
    let getAge = prototype.getAge;

    new Person().getAge(); 

    prototype.getAge(); 

    getAge(); 
</script>
</body>
</html>

大家可以嘗試做一下這道題,看下會輸出怎麼樣的結果?
如果把構造函數註釋代碼放開呢?結果會不會一樣

公佈結果: 18 38 undefined
如果把註釋代碼放開的結果是:88 38 undefined

箭頭函數中 this的

  1. 箭頭函數中本身是沒有this和argument的
  2. 默認指向定義它時,所處上下文的對象的this指向。即ES6箭頭函數裏this的指向就是上下文裏對象this指向,偶爾沒有上下文對象,this就指向window
  3. 即使是call,apply,bind等方法也不能改變箭頭函數this的指向
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let obj = {
        a: 1,
        fn: ()=>{
            console.log(this);
        }
    }
    obj.fn.call(obj);
</script>
</body>
</html>

如果正常的話,這個this指向的是obj,但是this指向的是window.這段代碼可以證明結論2.

如何改變this指向

javascript Function中 bind()、call()、 apply()用法詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章