深入理解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()用法详解

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