深刻浅出this的理解

this在js中一直是谜同样的存在着,在面试中也是常常会被问道,接下来总结下我所理解的this
首先引入秘密花园中对this的工做原理,文中指出有五种状况,分别是:javascript

  • 全局范围内
this;    //在全局范围内使用`this`,它将会指向全局对象复制代码
  • 函数调用
foo();    //this指向全局对象复制代码
  • 方法调用
test.foo();    //this指向test对象复制代码
  • 调用构造函数
new foo();    //函数与new一块使用即构造函数,this指向新建立的对象复制代码
  • 显式的设置this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]);    //this被设置成bar
foo.call(bar, 1, 2, 3);    //this被设置成bar复制代码

从函数调用理解this

有这样一道题java

var obj = {
    func: function(){
        console.log(this);
    }
}

var foo = obj.func;
obj.func() //this是obj
foo() //this是window复制代码

解释函数结果为何不同?git

这道题能够从函数调用来理解,从我看到的博文中有这样的解释,秘密花园中的函数调用,方法调用,显式的设置this都属于函数调用,至关于函数调用的三种方式,能够写成github

foo(params);
obj.child.foo(params);
foo.call(context, params); //apply同理复制代码

并且前两种均可以写成第三种形式面试

foo(params); =>> foo.call(undefined, params);

obj.child.foo(); =>> obj.child.foo.call(obj.child, params);复制代码

因此说函数调用都是foo.call(context, params)的变体,即函数调用只有一种。这样this的值就是文中的contextthis就是你函数调用时传入的context浏览器

举例代码中:app

function foo() {
    console.log(this);
}

foo();复制代码

当你没法确认this指代的值时,转化成call形式会更好理解ide

function foo() {
    console.log(this);
}

foo.call(undefined); //or foo.call();复制代码

函数执行结果为window,在浏览器中有一条规定,传入contextnullundefined时,则为全局对象(window对象);严格模式下contextundefined函数

举例代码中:ui

var obj = {
    func: function foo() {
        console.log(this);
    }
}

obj.foo();复制代码

转化为call形式为

var obj = {
    func: function foo() {
        console.log(this);
    }
}

obj.foo.call(obj);复制代码

很明显,this指代obj。

Event Handler 中的this

btn.addEventListener('click' ,function handler(){
  console.log(this) // 请问这里的 this 是什么
})复制代码

handler 中的this是什么?用上面的方法好像无法转化了,由于不知道addEventListener内源码实现,查看文档MDN

一般来讲this的值是触发事件的元素的引用,这种特性在多个类似的元素使用同一个通用事件监听器时很是让人满意。

当使用 addEventListener() 为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值同样。

因此能够假设浏览器addEventListener是这样实现的

// 当事件被触发时
handler.call(event.currentTarget, event) // this => event.currentTarget复制代码

以上就是对this的理解,若有错误请狠拍砖。

相关文章
相关标签/搜索