【问题标题】:In Javascript, is it true that function aliasing works as long as the function being aliased doesn't touch "this"?在Javascript中,只要被别名的函数不触及“this”,函数别名是否真的有效?
【发布时间】:2011-02-16 06:08:58
【问题描述】:

在 Javascript 中,如果我们为一个函数起别名(或者,将“对函数的引用”分配给另一个变量),例如:

f = g;
f = obj.display;
obj.f = foo;

以上所有 3 行,只要右侧的函数/方法不触及this,它们就可以工作?由于我们要传入所有参数,因此唯一可以搞砸的方法是右边的函数/方法使用this?

实际上,如果g 也是window 的属性,那么第1 行可能没问题?如果g 引用了obj.display,那么就会出现同样的问题。

在第2行中,obj.display接触this时,表示obj,但调用f时,thiswindow,所以它们是不同的。

在第 3 行中,也是一样的:当在 obj 的代码内部调用 f 时,则 thisobj,而 foo 可能使用 this 来引用window 如果它是 window 的属性。 (全局函数)。

所以第2行可以写成

f = function() { obj.display.apply(obj, arguments) }

和第 3 行:

obj.f = function() { foo.apply(window, arguments) }

这是正确的方法吗?除此之外还有其他方法吗?

【问题讨论】:

  • 这让我想到了 M.C.锤子
  • 我知道。我试图在原始问题中不提及这一点。
  • 恭喜,您刚刚发现了我讨厌 Javascript 中的面向对象编程的原因。由于缺少绑定函数,您始终必须注意上下文以及(因此) this 指向的内容。现在您可以继续学习真正的 OOP 语言了(抱歉 :)。

标签: javascript binding call apply


【解决方案1】:

基本上是的,但是,在 JavaScript 中,函数是第一类对象,所以它并不是真正的别名。您正在做的是将一个变量的值分配给另一个变量,在这种情况下,该值恰好是一个函数。

神奇的 this 变量有点不同。在 JavaScript 中,方法不像在大多数其他语言中那样绑定到类或对象。当您调用方法时,this 由点运算符设置,或者由 applycall 方法设置。它的工作原理是这样的:

var i = 1;
var f = function () { alert(this.i); }
f(); // in a browser, alerts 1, because this will be window if it isn't anything else.

var obj = { i: 10 };
obj.g = f;
obj.g(); // alerts 10, because the dot binds this to obj

var other_obj = { i: 23 };
f.apply(g); // alerts 23, because now apply binds this to other_obj

您可以使用闭包将方法绑定到对象:

var f = function () { alert(this.i); }
var obj = { i: 10 };

obj.m = function () { f.apply(obj); }
obj.m(); // alerts 10

var g = obj.m;
g(); // alerts 10, because now the closure is called, which binds this correctly.

【讨论】:

    【解决方案2】:

    如果你以这种方式调用一个对象,'this' 只会在你的函数中引用正确的对象:

    obj.f();
    

    这永远不会奏效,因为 javascript 缺乏对“绑定函数”的支持(不记得方法属于哪个对象):

    var x = context.lineTo;
    x(10,10);
    

    lineTo 会混淆,因为 'this' 现在指向窗口或当前函数对象,而不是其预期的上下文。所以确实,你总是需要申请。

    【讨论】:

      【解决方案3】:

      “this”的含义和适用于函数(尤其是回调)的作用域似乎是经典的 JavaScript“陷阱”。

      Dojo 有一个hitch() 方法可以解决这个问题,提供了一种很好的方法来获取回调方法的预期上下文。我想非 Dojo 开发人员可以看看 Dojo hitch() 代码来借鉴这些想法。

      article 解释了“this”问题的某些方面以及如何使用 Dojo hitch()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-22
        • 1970-01-01
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 2012-08-29
        • 1970-01-01
        • 2010-09-16
        相关资源
        最近更新 更多