我试图理解“这个”,我所看到的一切都是关于背景的。这让我想到的是“这个”是一个范围限制器。它确保使用适当的范围引用变量,主要是通过将变量保持在“本地”范围内,并使它们远离运行代码的位置。
我的问题是:这是正确的吗?我尝试使用我想要的概念进行搜索,但是那些结果非常糟糕。 “这个”有很多细微之处,从我所做的阅读中,我觉得这比我所看到的更好,但我想确保我的思维正确。
答案 0 :(得分:3)
this
和变量范围是不同的概念。变量范围是指可以从应用程序中的哪个位置访问哪些变量。仅仅因为你在某个地方写了var foo
并不意味着你可以从整个代码库中的到处访问它。在Javascript中,每个function
引入了一个新的范围,范围以内部函数可以访问外部函数范围的方式嵌套,但反之亦然。
this
只是对“当前”对象的“魔术”引用。也许首先在其他经典语言的背景下解释这个想法是有帮助的:
class Foo {
protected $bar;
public function baz() {
echo $this->bar;
}
}
在PHP中,magic关键字$this
引用当前对象实例。每次调用new Foo
时,都会创建此类的新实例。每次调用$foo->baz()
时,都会执行相同的函数,但$this
设置为相应的对象实例,因此每个对象实例都可以访问自己的数据。
在Python中,这实际上更加明确:
class Foo:
def baz(self):
print self.bar
Python没有magic关键字来引用当前对象实例。相反,对对象的每个方法调用都会将当前对象显式传递为第一个参数。这通常命名为self
。如果Python对你来说太陌生了,PHP语法中的上述内容将是:
class Foo {
public function baz($this) {
echo $this->bar;
}
}
从技术上讲,这些类中的函数并不真正“属于”任何“类”。它们只是功能。您只需要某些方法让这些函数能够引用多态对象,以使它们成为实例方法。举个例子:
function baz($obj) {
echo $obj->baz;
}
这与上面的类方法完全相同,区别在于$obj
被明确注入而不是$this
被神奇地“存在”。
Javascript具有相同的功能,除了{em>每个函数(不仅仅是“类”函数)中this
可用,并且对象this
指向的对象可以自由在运行时更改。 this
只是一个指向对象的魔术关键字,句号。
function Foo() {
this.bar = null;
this.baz = function () {
console.log(this.bar);
}
}
在foo.baz()
等对象上调用常规函数时,this
通常会引用foo
内的baz()
;虽然它真的没有:
foo.baz.apply(someOtherObj);
这会使用foo.baz
函数并在将this
内的baz
关键字设置为someOtherObj
时调用它。如果愿意,它可以自由地将函数与另一个对象实例重新关联。但这只是因为首先将函数“绑定”到对象的唯一因素是this
关键字。无论console.log(this.bar)
指的是什么,该函数仍然只会this.bar
。
更完整的例子:
function Foo() {
this.bar = 'baz';
}
Foo.prototype.speak = function () {
alert(this.bar);
};
var o = new Foo();
o.speak(); // alerts 'baz'
alert(o.bar); // also alerts 'baz'
var o2 = { bar : 42 };
o.speak.apply(o2); // alerts 42
如您所见,this
并非限制任何内容的范围。这里发生了什么?
使用Foo
调用new Foo()
构造函数。 new
只是创建一个新对象,并执行Foo()
并将this
设置为此新对象。基本上是:
var tmp = {}; // tmp does not *actually* exist,
// that's more or less what `new` does behind the scenes
Foo.apply(tmp);
Foo
构造函数指定该新对象的bar
属性。
tmp.bar = 'baz';
新对象已分配到o
。
var o = tmp;
o.speak()
是通过其prototype
绑定到该对象的函数。将其称为o.speak()
,this
内的speak()
指的是o
对象。由于该对象具有属性bar
,因此可以使用。
alert(o.bar)
。 .bar
属性最初设置在this
,然后this
变为o
。因此o
具有属性.bar
,它是对象的常规属性。它不受范围限制或任何限制。o2
,它也恰好具有bar
属性。然后我们致电o.speak
,但我们明确覆盖this
使用apply
所指的内容的选择。我们只是对this
关键字引用的对象进行切换。因此,speak
函数会警告bar
对象的o2
属性。正如你所看到的那样(希望我知道这首先可能是大脑弯曲),this
只不过是一个对象的引用。就这样。它不会在所有范围内限制。 function
的限制范围,this
只是一个任意对象。您在this
上设置的任何内容不限于范围;相反,它总是可以从您访问该对象的任何地方公开访问。
令人难以置信的是,一旦你设法绕过它,这一切都是微不足道的。 this
指的是一个对象,它只是Javascript的魔术关键字,用于引用一个对象。在任何给定时间,它都会引用某些 对象的简单规则,但所有这些规则都可以弯曲和折断并重新分配。对象只是具有属性的 a 。属性可以是函数。只有函数限制变量范围。这就是它的全部内容。不要试图将其他任何内容解释为此。