我试图理解“这个”,并且我所看过的所有内容都在谈论上下文。这导致我想到“ this”是范围限制器的想法。它可以确保使用适当的范围来引用变量,主要是通过使变量在范围内保持“局部” -ish,并防止它们与运行代码所在的位置相距太远。
我的问题是:正确吗?我尝试使用试图传达的概念进行搜索,但是结果却完全不对。 “ this”有很多细微差别,从我读过的书中,我觉得这比我看过的要好,但我想确保自己的想法是正确的。
最佳答案
this
和变量作用域是独立的概念。变量范围是指可以从应用程序中的任何位置访问哪些变量。仅仅因为您在某处写了var foo
并不意味着您可以在整个代码库中的任何地方访问它。在Javascript中,每个function
都引入了一个新的作用域,并且作用域嵌套的方式是内部函数可以访问外部函数的范围,反之亦然。
另一方面,this
只是对“当前”对象的“魔术”引用。也许首先在其他古典语言的背景下解释这个想法可能会有所帮助:
class Foo {
protected $bar;
public function baz() {
echo $this->bar;
}
}
在PHP中,魔术关键字
$this
指向当前对象实例。每次调用new Foo
时,都会创建此类的新实例。每次调用$foo->baz()
时,都会执行相同的功能,尽管将$this
设置为适当的对象实例,这样每个对象实例都可以访问自己的数据。在Python中,这实际上更为明确:
class Foo:
def baz(self):
print self.bar
Python没有魔术关键字来引用当前对象实例。取而代之的是,对对象的每个方法调用都将当前对象显式传递为其第一个参数。通常将其命名为
self
。如果Python对您来说似乎太陌生,则PHP语法中的上述内容应为:class Foo {
public function baz($this) {
echo $this->bar;
}
}
从技术上讲,这些类中的功能并不真正“属于”任何“类”。它们只是功能。您只需要为这些函数提供某种方法就能够引用多态对象,以使其成为实例方法。举个例子:
function baz($obj) {
echo $obj->baz;
}
这基本上与上面的类方法完全相同,不同之处在于显式注入了
$obj
而不是神奇地“存在”了$this
。除了具有
this
在每个函数中可用(不仅是“类”函数)而且对象this
指向的对象可以在运行时自由更改之外,Javascript也具有相同的功能。 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引用对象的magic关键字。在任何给定时间,它所引用的对象都有某些琐碎的规则,但是所有这些规则都可以弯曲,折断和重新分配。对象只是具有属性的事物。这些属性可以是函数。仅函数限制变量范围。这几乎就是它的全部。请勿尝试对此进行任何其他解释。
关于javascript - “这个”作为范围限制器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24783466/