“this”关键字的引用对象是否可以在没有新运算符或调用apply()/ call()函数的情况下更改?

时间:2013-11-14 14:56:43

标签: javascript jquery

我正在研究如何制作jquery插件。

这是我的代码:

<!DOCTYPE html>
<html>
<head>
<title>JS Study</title>
</head>
<body>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
(function($, undefined) {
    function MyPlugin() {
        this.myoption = "myvalue";
    }

    $.extend(MyPlugin.prototype, {
        _attachMyPlugin: function(target, settings) {
            console.log(this); // check2
        }
    });

    $.fn.myPlugin = function(options) {
        console.log(this); // check1
        $.myPlugin._attachMyPlugin(this, options);
        return this;
    };

    $.myPlugin = new MyPlugin(); // singleton instance
}(jQuery));
$(document).ready(function(){
    $("#abc").myPlugin();
});
</script>
<h1 id="abc">title1</h1>
</body>
</html>

当我调用_attachMyPlugin()时,我不知道为什么this的值会发生变化。 在check1 this似乎只是引用一个jQuery对象。这对我来说似乎并不奇怪。 但是在check2'这个'似乎是指MyPlugin对象。为什么呢?

this关键字的引用对象是否可以在没有new运算符或调用.apply() / .call()函数的情况下更改?如果是这样的话?

以下是Chrome控制台的结果。

  

[h1#abc,context:document,selector:“#abc”,jquery:“1.9.1”,constructor:function,init:function ...]    w.html:21   MyPlugin {myoption:“myvalue”,_ attachMyPlugin:function}    w.html:16

3 个答案:

答案 0 :(得分:1)

通常在函数内部,this的值是调用函数的对象:

var a = {
  b : { 
    c : function() {
      console.log(this);
    }
  }
};

a.b.c() // this will be a.b

var d = {};
d.e = a.b.c;

d.e() // this will be d

var f = a.b.c;

f() // this will be the global object (usually window) or undefined (strict mode)

显然callapply允许你覆盖它并将其他对象传递给函数。还有一个值得注意的例外:bind。 Bind创建一个新函数,该函数始终在传递给bind的对象上调用。它通过使用apply来实现这一点(检查MDN的近似实现)。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

应用于您的代码:

$("#abc").myPlugin(); // check1 this is $("#abc")

$.myPlugin._attachMyPlugin(this, options); // check2 this is $.myPlugin (which is an instance of MyPlugin)

答案 1 :(得分:0)

this仅在函数与.apply或.call一起使用时更改,如果它是一个事件,或者它被取消了上下文(稍后会更多)。

例如,我们有这段代码:

var foo = {
    myFunction: function(){
        console.log(this);
    },
    bar: "foobar"
}

只要我们将myFunction作为foo的属性执行而不是应用或调用,this将为foo

foo.myFunction(); // foobar
foo.bar = "Hello World!";
foo.myFunction(); // Hello World!

现在,如果我们绑定一个click事件并将其处理程序设置为foo.myFunctionthis将成为元素。

$("#abc").click(foo.myFunction); // HTMLDomNode (after a click)

现在,如果您将foo.myfunction存储在另一个变量中然后执行它,那么this将成为窗口,因为它的引用不再是foo的一部分。

var bar = foo.myFunction;
bar(); // window

演示:http://jsfiddle.net/9V9S7/

答案 2 :(得分:0)

$。myPlugin - MyPlugin类的实例。方法_attachMyPlugin()属于MyPlugin实例。当你调用这个方法时,“this”指向$ .myplugin对象。 当你调用$ .fn.someFunction时,“this”指向jQuery对象,$(“#abc”)