为什么“这个”分辨率在JavaScript中如此特别?

问题描述

| 警告:错误的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>\");
可以看出,
increment_helper
中的
this
而是指全局作用域(或者,如果我理解正确的话,是指
window
范围),而不是指封闭的闭包。这样,输出将是:   0 代替   1个 我将列出更好的解决方案(仍不完美,但还可以),然后提出主要问题。因此,解决方案(IMHO)可以像这样进行分类
// 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中与众不同?为什么只有ѭ1,又是什么目的? 非常感谢! 更新:在下面@Jordan的评论(他解释了相对变量(如
this
)和范围变量(如常规变量)之间的区别)后,我改了一下我的问题: 答:相对变量背后的一般原理是什么? B:为什么ѭ1是JavaScript中唯一的相对变量?为什么相对/范围概念可以(专门)应用于每个变量有任何理由?     

解决方法

        答:在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。因此ѭ1必须是相对的。是的,这会引起问题,但是这种语言会令人难以置信地表现出来。 B.
arguments
也是相对的。     ,        本文将使您对\“ this \”在javascript中的工作方式有深入的了解。     ,        JavaScript仅在表面上类似于Java。当您浏览语法时,会发现对象模型完全不同(没有类),并且它比面向对象的更像是一种功能语言。由于市场营销的原因,Netscape希望JavaScript看起来像Java。为此,它获得了一些您可能不会想到的功能,例如按位运算符(使用没有整数数据类型的脚本语言)。
this
是这些功能之一。 从历史上看,之所以用“ 1”来定义它,是因为与设计人员在模仿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的实例。