编辑:对于那些将来看到这篇文章的人,this site毫无疑问,这对我消化 Javascript 至关重要。如果您来自传统的 OOP 背景,我强烈推荐它。 UML-esq 图非常棒。
我仍然无法理解 Javascript 中的 .prototype 属性是什么。它只是对另一个对象的引用吗?或者它是指向另一个对象的指针的引用?我来自 C/C++/x86,只是看不到它是如何工作的。让我们看一些我目前如何看待事物的例子;它有助于指出我的错误,看看事情是如何工作的。我什至不知道其中一些是否是有效的语法。 Object
和Function
分别是全局对象/函数对象。
1 // Global.prototype = ??
2 // Function.prototype = ??
3
4 var obj1 = {}; // obj1.prototype = Object
5 obj2 = {}; // obj2.prototype = Object
6
7 var func1 = function() {}; // func1.prototype = Function
8 func2 = function() {}; // func2.prototype = Function
9 function func3() {} // func3.prototype = Function
10
我很困惑。
11 var Foo = function() { this.prop1 = 0; }
12 var foo = new Foo(); // should it be 'new Foo' or 'new Foo()'?
13 // Foo.prototype = Function
14 // foo.prototype = Foo
15 var Goo = function() { this.prop2 = 0; }
16 var goo = new Goo();
17 // goo.prototype = Goo
18 goo.prototype = new Foo();
19 // goo.prop1 now exists ?
我也不明白交换原型(prototype)。
20 function A () {
21 this.prop1 = 1;
22 }
23 function B () {
24 this.prop2 = 2;
25 }
26 function C () {
27 this.prop3 = 3;
28 }
29 C.prototype = new B();
30 var c = new C();
31 // c.prop1 = 1
32 // c.prop2 = 2
33 // c.prop3 = undefined
34 C.prototype = new A();
35 // c.prop2 = 2???
36 // c.prop3 = 3
我无法理解这个概念。我不太明白。我不明白克隆对象如何获得它们自己的本地数据副本,但对原始对象(原型(prototype))的更改以某种方式级联到克隆。我一直在摆弄 FigureBug 尝试解决问题,但在精神上我无法想出一个与我见过的每个例子都一致的想法
C++ 可能是一个巨大的怪物,但至少我确切地知道发生了什么。在这里...我正在使用我最好的猜测.. 我想这只是一个新范例。无论如何,如果你能帮忙,谢谢...我对这个 .prototype 感到很困惑。
最佳答案
哇,这么多问题。让我们来解决它们。
Is it simply a reference to another object? Or is it a reference to a pointer to another object?
JavaScript 中没有指针。然而,持有“对象”的变量或属性实际上持有对该对象的引用,因此其他变量可以持有对同一对象的引用。
Global.prototype = ??
定义所有全局变量的全局对象(window
)没有原型(prototype)(不关心某些环境中的异常)。
I still can't get my head around what the .prototype property in Javascript is.
.prototype
属性是所有函数对象都具有的属性,指向它们的原型(prototype)对象(普通对象)。
您不能将它与每个对象具有的内部原型(prototype) 引用混淆。 原型(prototype) 指向对象,在该对象中查找对象本身没有的属性。
Function.prototype = ??
这是所有 Function 对象继承自的对象。它包含诸如 call
或 bind
之类的内容。
var obj1 = {}; // obj1.prototype = Object var func1 = function() {}; // func1.prototype = Function
是的,有点。我认为您已经了解了这个概念,但不知道术语。虽然 func.prototype
是另一回事,但 obj.prototype
属性甚至不存在。但是,您指的是内部原型(prototype) - 我们可以通过 Object.getPrototypeOf
函数访问它们。而且它们不引用构造函数,而是引用它们的原型(prototype)对象。更正如下:
Object.getPrototypeOf(obj1) === Object.prototype
Object.getPrototypeOf(func1) === Function.prototype
should it be 'new Foo' or 'new Foo()'?
没关系,它们是等价的。当您想要传递参数时,您只需要显式地使用方括号。
var Foo = function() { this.prop1 = 0; } var foo = new Foo();
同样,您的假设是正确的,但表达错误。让我们详细了解一下。
上面,我谈到了“原型(prototype)对象”。那些是什么?它们是通过每个函数隐式创建的普通对象。在本例中,它是 Foo.prototype
- 一个空对象。所以我们在这里处理三个对象:Foo
构造函数、它的 Foo.prototype
原型(prototype)对象和 foo
实例。
foo
有什么特别之处?这是 new
运算符做的第一件事。当一个函数作为构造函数被调用时 - 使用 new
- 然后它的 .prototype
属性被访问并用它的内部原型(prototype) 设置为该原型(prototype)对象。这就是神奇的事情。之后在新实例上调用该函数,这样 this
就是新对象;在您的情况下,它会在实例上创建 .prop1
属性。然后返回结果(并分配给 foo
)。
现在如何使用那个魔法?重点是在原型(prototype)对象上创建属性,然后将继承这些属性。
// modify `Foo.prototype`, the object which `foo` inherits from:
Foo.prototype.prop2 = 1;
console.log(foo.prop2); // 1!
I also don't understand swapping prototypes around.
问题是这是不可能的。一旦实例化,一个对象的原型(prototype)链是相当静态的。但是,您并不经常需要这样做。
goo.prototype = new Foo();
这不起作用,因为 .prototype
属性不是您所期望的。
var c = new C(); C.prototype = new A();
这只起到了一点点作用。看看上面的 new
做了什么——它只查找构造函数的 .prototype
属性一次。内部 prototype 然后保持锁定状态 - 您不会更改 c
实例。但是,如果您现在要创建一个新实例 var d = new C()
,那么它将继承自 A
实例。
希望对您有所帮助;如果您还有其他问题,请发表评论。
关于javascript - 学习.prototype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17660090/