JavaScript 分享 - JS - 函数中的 this

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

参考文献:
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() ); });

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

共收到 5 条回复
zouyu 回复

Thanks buddy

‘this’ is a 坑!

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

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

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