为什么'这个'解决方案在JavaScript中如此特别?

时间:2011-06-14 15:36:19

标签: javascript programming-languages functional-programming

警告:首先是Buggy JavaScript代码!

// 1: buggy counter
// -----------------
// problem: 'this' can be "broken"
var Counter1 = function() {
    this.count = 0;
    this.increment = function() {
        function increment_helper(){
            ++this.count; // this refers to window (global), not to the object that Counter1 was called with
        }
        increment_helper();
    }
    this.reset = function() { this.count = 0; }
    this.get_count = function() { return this.count; }
}

var counter1 = new Counter1();
counter1.increment();
document.writeln("<p> 1: " + counter1.get_count() + "</p>");

正如可以看到的那样,this中的increment_helper指的是全局范围(或​​window范围,如果我说得对,则要精确),而不是引用这封闭的封闭物。所以,输出将是:

  

0

而不是

  

1

我会列出更好(仍然不完美,但没问题)的解决方案然后会问主要问题。因此,解决方案(恕我直言)可以像这样整理:

// 2: better counter
// -----------------
// solved: 'that' can't be "broken"
var Counter2 = function() {
    var that = this;
    that.count = 0;
    that.increment = function() {
        function increment_helper(){
            ++that.count; // that refers right to the object the Counter1 was called with
        }
        increment_helper();
    }
    that.reset = function() { that.count = 0; }
    that.get_count = function() { return that.count; }
}

var counter2 = new Counter2();
counter2.increment();
document.writeln("<p> 2: " + counter2.get_count() + "</p>");

所以,主要问题是:为什么this与JavaScript中的其他人一样特殊?为什么它只是this以及出于什么目的?

非常感谢!

更新:关注@ Jordan的评论(他解释了相对变量之间的区别,如this范围变量之类的常规的),改写我的问题:

答:相对变量背后的一般原理是什么?

B:为什么this是JavaScript中唯一的相对变量?关于为什么相对/范围概念可以(专门)应用于每个变量的任何理由?

3 个答案:

答案 0 :(得分:2)

一个。在JavaScript中,与其他类似C语言的OO语言不同,函数是第一类对象。您可以复制函数,将它们传递给其他函数,从函数返回它们,创建新函数。函数类似于Java或C#中永久附加到类声明的方法。这意味着this必须与函数本身及其调用方式相关。否则就没有意义了。

这是一个愚蠢的例子:

var o = {
  name: "My name is o",
  foo: function () { alert(this.name); }
};

var p = {
  name: "My name is p",
};

p.foo = o.foo;
p.foo(); // "My name is p"

在其他OO C类型语言中无法做到,但它可以在JavaScript中完成。因此this必须是相对的。是的,它会导致问题,但语言变得非常表达

B中。 arguments也是相对的。

答案 1 :(得分:2)

article将让您深入了解“此”在javascript中的工作原理。

答案 2 :(得分:1)

JavaScript与Java只有表面上的相似之处。当您查看语法时,您会注意到对象模型完全不同(没有类),它更像是一种功能语言,而不是面向对象的语言。出于营销原因,Netscape希望JavaScript看起来像Java。为此,它选择了一些您可能没有预料到的功能,例如按位运算符(在没有整数数据类型的脚本语言中)。 this是其中一项功能。

从历史上看,this的定义原因是因为它与设计师一样可以模仿Java中的含义。

另外,请考虑在Java中编写最近的等效代码时会发生什么:

class Foo {
    int count = 0;
    IncrementHelper helper = new IncrementHelper() {
        public void increment() {
            ++this.count; // doesn't compile
        }
    }

    public void increment() { helper.increment(); }
    public void reset() { this.count = 0; }
    public int getCount() { return this.count; }
}

指示的行甚至不编译(你必须说++Foo.this.count)因为在内部类中,this不是Foo的实例。