6

先进到和魔法无异的 JavaScript this

 3 years ago
source link: http://misaka.im/index.php/archives/64/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

this 为何而生

随着你的使用模式越来越复杂,显示传递上下文对象会让代码变得越来越乱,使用 this 这不会。

this 提供了一种更优雅得方式来隐式“传递”一个对象引用,因此可以将 API 设计得更加简洁并且易于复用。

this 在任何情况下都不指向函数的词法作用域,this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用

把人绕晕的题目

开发者往往会把理解 this 的过程复杂化,并把它作为进阶中高级开发者的门槛。即使是非常有经验的 JavaScript 开发者也很难说清楚它到底指向什么。

var fullName = 'a';
var obj = {
    fullName: 'b',
    prop:{
        fullName: 'c',
        getFullName: function(){
            console.log(this);
            return this.fullName
        }
    }
}

console.log(obj.prop.getFullName());

var test = obj.prop.getFullName;
console.log(test());
JavaScript
console.log(obj.prop.getFullName())

严格来说 getFullName() 函数不属于 obj 对象,但调用位置会使用 obj 上下文来引用函数。

//console.log(this);
{fullName: "c", getFullName: ƒ}

c
JavaScript

getFullName() 函数被调用时,obj 对象包含了它,隐式绑定规则会把函数调用的 this 绑定到 obj 上下文,因此 thisobj.prop 是一样的;

console.log(test())
a
JavaScript

test 变量通过别名的方式引用了 getFullName() 函数,此时 test() 是一个不带任何修饰的函数调用,因此应用了默认绑定 ,this 指向全局对象


var num = 1;
var myObject = {
    num: 2,
    add: function() {
        this.num = 3;
        (function() {
            console.log(this.num);
            this.num = 4;
        })();
        console.log(this.num);
    },
    sub: function() {
        console.log(this.num)
    }
}


myObject.add();

console.log(myObject.num);

console.log(num);

var sub = myObject.sub;
sub();
JavaScript
myObject.add()

add 函数中含有匿名函数,在匿名函数中 this 被重新绑定到全局对象,所以匿名函数中的 this 是 window ;最后修改 window.num 为 4

JavaScript

add 函数执行时 隐式绑定myObject 上下文,一般情况下此时的 this 就是 myObject

this.num = 3; 率先将 myObject.num 赋值为 3

3
JavaScript
console.log(myObject.num)

add 函数执行后修改了 myObject.num 为 3

3
JavaScript
console.log(num)

这里的 num 指的是 window.numadd 函数中的匿名函数执行后修改了 window.num 为 4

4
JavaScript
sub()

sub 变量是 myObject.sub() 函数的引用,此时 sub() 是一个不带任何修饰的函数调用,因此应用了默认绑定 ,this 指向全局对象,即是 window.num

4
JavaScript
new 绑定

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK