JavaScript 分享 - JS - 函数中的 this

hiveer · 2018年10月25日 · 最后由 Choicelin 回复于 2019年06月22日 · 5968 次阅读

参考文献:
https://www.cnblogs.com/ifantastic/p/4654370.html
http://api.jquery.com/bind/

任何代码都需要一个上下文来执行,而this就是这个上下文。

这里直接借用参考文献中的例子:

// 假设这段代码是在浏览器的全局环境中
function getUrl() {
    console.log(this.document.URL);
}

var pseudoWindow = {
    document: {
        URL: "I'm fake URL"
    },

    getUrl1: getUrl,

    getUrl2: function (callback) {
        callback();

        this.func = callback;
        this.func();
    }
}

那么,getUrl, pseudoWindow 现在所处的上下文就是 window, 也就是说此时的 this === window。
所以执行 getUrl(),将打印出当前页面的 URL。

那么执行 pseudoWindow.getUrl1() 情况会是怎么样的呢?

getUrl1 是 pseudoWindow 的一个属性,可以理解为是绑定到 pseudoWindow 上下文的一个变量。而这个变量 getUrl1 使用了和 getUrl 相同的代码片段。
所以,这里的调用实际上是把相同的代码的片段放在了一个不同于 window 的上下文 pseudoWindow 中来执行。
此时this就是 pseudoWindow,所以打印出的结果将是 I'm fake URL。

那么执行 pseudoWindow.getUrl2(getUrl) 的情况呢?

对于 getUrl2 情况类似于 getUrl1,关键是在匿名函数接收了一个参数,这个参数是一个 global 的函数对象。
因为这里传入的 getUrl 没有和任何上下文关联,所以在匿名函数中执行的时候,它的上下文还是 window。
this.func = callback; 这个表达式的效果跟 getUrl1 完全类似,差别在于这里隐式的给 pseudoWindow 设置了一个属性。
所以打印结果是: 当前页面的 URL, I'm fake URL。

对于 getUrl2 中 callback 参数,如果想要拿到当前匿名函数的 this 为上下文,我们可以这么做:

getUrl2: function (callback) {
    callback();        
    callback.apply(this);
}

看到这里我就想起了我们在使用 jQuery 的时候常看到这样的写法:

$( "p" ).click(function() {
  $( this ).slideUp();
});

这看起来和 getUrl2 种的 callback 很相似,所以我就 confusing 了!!!! 如果是一样的,那么在这里 this 应该是 window 啊,但是明显不是。所以我就去 jQuery 文档找啊找……^_^
终于被我找到了:
在 jQuery 中,这个函数被叫做 handler,然后有这样的陈述:

Event Handlers The handler parameter takes a callback function, as shown above. Within the handler, the keyword this refers to the DOM element to which the handler is bound. To make use of the element in jQuery, it can be passed to the normal $() function. For example: $( "#foo" ).bind( "click", function() { alert( $( this ).text() ); });

所以,我的疑惑算是消除了, 你的呢?

zouyu 回复

Thanks buddy

‘this’ is a 坑!

写的很好,看完你的之后,我还有一个疑惑,obj.obj2.getUrl(),这种 this 是 obj 还是 obj2

同样,this 的绑定只受最靠近的成员引用的影响。在下面的这个例子中,我们把一个方法 g 当作对象 o.b 的函数调用。在这次执行期间,函数中的 this 将指向 o.b。事实证明,这与他是对象 o 的成员没有多大关系,最靠近的引用才是最重要的。 @Choicelin 在浏览了 mdn 后 自问自答 😍

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册