jQuery Function Extend的范围问题

时间:2014-05-05 21:08:11

标签: javascript jquery extend

我正在尝试扩展对象并且该对象包含多个函数。我无法解释它,所以让我告诉你我的代码。让我们从正在发挥作用开始:

(function ($) {
    $.fn.extend({
        Hello: function() {
            console.log("Well, hello back!");
            console.log($(this));
        }
    });
})(jQuery);

在HTML中:

<script>
    $(document).ready(function() {
        $('.target').Hello();
    });
</script>

$(this)的控制台日志正如预期的那样向我提供被调用元素&#34; target&#34 ;.

现在,让我们这样试试:

(function ($) {
    $.fn.extend({
        Response: {
            Hello: function() {
                console.log("Well, hello back!");
                console.log($(this));
            }
        }
    });
})(jQuery);

在HTML中:

<script>
    $(document).ready(function() {
        $('.target').Response.Hello();
    });
</script>

这仍然是吐出来的#34;好吧,你好回来!&#34;在控制台中,但是当我使用$(this)时,我不再收到被叫方。我得到了Hello函数。

我如何获得被叫方?我试过这个.parent,这不起作用。请帮忙!

3 个答案:

答案 0 :(得分:1)

你不能真的这样做 - 这是非常不切实际的。

JavaScript中有一些特殊规则决定调用函数时this的值是什么。其中之一是,只要表单中包含foo.bar()表单,就会调用barthis评估为foo来进行调用。

因此,当您运行$('.target').Response.Hello()时,this等于$.fn.Response,而不是包裹.target的jQuery对象。

您可以通过使用例如覆盖this的分配来获得所需的行为。 Function.prototype.call

var $target = $('.target');
$target.Response.Hello.call($target);

当然这很麻烦,但没有太多选择。在理论上我能想到的唯一其他解决方案涉及将代码注入jQuery的想法,以便$$.Response解析为每个jQuery实例$$不同的东西。如果问题的目的只是为了实现首选语法,那么这可能有点过头了。

答案 1 :(得分:1)

正如其他人所指出的那样,你可以真正做到你所要求的,但你可以做一些看起来几乎相同的事情。

通过捕捉这个&#39;使用闭包,您可以在对象结构中进一步访问它:

$.fn.extend({
    Response: function () {
        var self = this;
        return {
            Hello: function () {
                console.log(self);
            }
        };
    }
});

$('.target').Response().Hello();

答案 2 :(得分:0)

不幸的是,JavaScript中的对象之间没有父子关系。这样做的原因是同一个对象可能有多个父对象。在处理嵌套对象时,这很难理解(如您提供的代码示例中的情况)。请考虑以下示例:

var foo = {
  bar: {
    baz: 1,
    biz: function() { console.log(this) } 
  }
}

foo.bar.biz();
=> { baz: 1, biz: [Function] }

var y = {};
y.foobar = foo.bar

y.foobar.biz();
=> { baz: 1, biz: [Function] }

在这两种情况下,对biz的调用将仅返回包含直接的对象。尝试通过bar关键字访问this对象的父级是不明确的,因为已经指定了多个父级。

在您的情况下,您最好的选择是使用call函数显式指定函数上下文:

var $target = $('.target');
$.fn.Response.Hello.call($target);