2013-07-15 95 views
8

编辑:对于那些未来看到这篇文章的人来说,this site对我来说无疑是消化Javascript的关键。如果你来自传统的面向对象的背景,我强烈推荐它。 UML-esq图很棒。学习。原型

我仍然无法弄清楚Javascript中的.prototype属性。它仅仅是对另一个对象的引用吗?或者它是对另一个对象的指针的引用?我来自C/C++/x86,却无法看到它是如何工作的。我们来看看我目前看到的东西的一些例子;它会帮助指出我的错误,看看事情是如何工作的。我甚至不知道其中的一些是否是有效的语法。 ObjectFunction分别是全局对象/函数对象。

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 ? 

我也不明白交换原型。

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 

我无法理解这个概念。我不太明白。我不明白克隆对象如何获得自己的本地数据副本,但对原始对象(原型)的更改以某种方式级联到克隆。我一直在试图FigureBug出来的东西摆弄周围,但精神上我不能想出一个想法,是与每一个例子我见过

C++可能是一个巨大的怪物一致的,但至少我知道确切发生了什么事。这里...我用我最好的猜测.. 只是一个新的范式,我想。无论如何,如果你能帮忙,谢谢......我在这个原型上倒过来了。

+0

检查我的回答这样一个问题:http://stackoverflow.com/questions/17047025/trying-to-understand-javascript-inheritence/17049716#17049716 – Hoffmann

+0

如果你问obj.x和OBJ没有它的自己的x属性,JS会检查obj.prototype.x的存在,如果存在,返回它,否则返回undefined。把它看作是编程的呼叫转移,原型是可以尝试访问数据的备用数字。由于它是不同的电话,如果替代品被毁坏,您仍然可以拨打主线。 – dandavis

+0

@dandavis好的,我明白了。我不明白什么.prototype引用,它默认设置为什么,以及当我开始交换原型的时候会发生什么? – gone

回答

4

哇,这是很多问题。让我们通过他们。

它仅仅是对另一个对象的引用吗?或者它是对另一个对象的指针的引用?

JavaScript中没有指针。然而,持有“一个对象”的变量或属性实际上持有对该对象的引用,所以其他变量可以保存对同一对象的引用。

Global.prototype = ?? 

全局对象(如果你想window),其中所有的全局变量的定义,没有原型(不关心在某些环境中的例外)。

我仍然无法理解JavaScript中的.prototype属性。

.prototype属性是所有函数对象都有指向其原型对象(普通对象)的属性。

您不能将它与每个对象具有的内部参考原型混淆。 原型指向查找属性的对象,而对象本身没有属性。

Function.prototype = ?? 

这是从中所有功能对象继承的对象。它包含诸如callbind之类的内容。

var obj1 = {};    // obj1.prototype = Object 
var func1 = function() {}; // func1.prototype = Function 

是的,有点。我认为你有这个概念,但不知道这个术语。虽然func.prototype是不同的事情,obj.prototype属性甚至不存在。但是,您的意思是内部原型 - 我们可以通过Object.getPrototypeOf函数访问它们。他们不引用构造函数,而是引用它们的原型对象。这里的修正:

Object.getPrototypeOf(obj1) === Object.prototype 
Object.getPrototypeOf(func1) === Function.prototype 

它应该是 '新富' 或 '新的Foo()'?

这并不重要,它们是等价的。当你想传递参数时,你只需要明确的需要括号。

var Foo = function() { this.prop1 = 0; } 
var foo = new Foo(); 

同样,你的假设是正确的,但表达错误。让我们通读细节。

上面我谈到了“原型对象”。那些是什么?它们是用每个函数隐式创建的普通对象。在这种情况下,它是Foo.prototype - 一个空的对象。所以我们在这里处理三个对象:Foo构造函数,其Foo.prototype原型对象和foo实例。

foo有什么特别之处?这是new运营商所做的第一件事。当一个函数被构造函数调用时 - 与new - 然后它的.prototype属性被访问,并且一个新对象被实例化,其内部原型被设置为该原型对象。这是奇迹般的事情。之后,在新实例上调用该函数,以便this是新对象;在你的情况下,它会在实例上创建.prop1属性。然后返回结果(并分配到foo)。

如何利用这个魔法呢?重点是在原型对象上创建属性,然后继承它。

// modify `Foo.prototype`, the object which `foo` inherits from: 
Foo.prototype.prop2 = 1; 
console.log(foo.prop2); // 1! 

我也不太了解周围交换原型。

的问题是,这是完全不可能的。一旦实例化,对象的原型链就非常静态。但是,你并不需要经常这样做。

goo.prototype = new Foo(); 

这并没有工作,因为.prototype属性是不是你所期望的。

var c = new C(); 
C.prototype = new A(); 

这不工作只是littlebit。看一下new的作用 - 它只查找构造函数的.prototype属性一次。内部原型保持锁定,然后 - 您不更改c实例。但是,如果您现在要创建一个新实例var d = new C(),那么它将从A实例继承。

我希望这有助于;如果您还有其他问题,请发表评论。

+0

对不起,我迟到了。但是,是的。就是这个。 “问题是,这是不可能的”:正是我所需要的(以及你提到的其他一切)>非常感谢;顶尖的答案伊莫 – gone

2

原型用于在读取期间对象本身没有定义的情况下搜索属性。写操作总是对象本身发生

当你调用

// An instance of Foo ({prop1:0}) is set as the 
// prototype (to all instances of Goo) 
var goo = new Goo(); 

// 0, from the prototype 
console.log(goo.prop1); 

// Read from the object itself (set in Goo's constructor) 
console.log(goo.prop2); 

// New instance, same prototype as goo 
var goo2 = new Goo(); 
console.log(goo2.prop1) ; // 0, still from the prototype 

// Setting is always at the object level, not the prototype 
goo.prop1 = 5; 

// goo2 is still reading from the prototype 
console.log(goo2.prop1); 

注:

不要实例化父类来设置继承。看看这里为什么http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html