2014-10-01 147 views
1

我无法理解普通对象和继承创建过程与整个概念之间的差异。比方说,我有这样的代码:Javascript原型继承和对象创建

function Person(name, age,location){ 
    this.name = name; 
    this.age = age; 
    this.location = location; 
    this.greet = function(){ 
     return console.log(this.name + " says hi from "+this.location); 
    } 
} 
    Person.prototype = { 
     protoGreet: function(){ 
      console.log(this.name + " says 'that greeting was sent using a prototype'") 
     } 
    } 

var alex = new Person("Alex",29,"earth"); 
var john = Object.create(Person); 
//now I can set john's location john.location = "wherever"; 
  1. 请告诉我greetprotoGreet方法之间的差异。他们都完全一样。
  2. alexjohn之间的区别是什么?其中一个是使用new关键字创建的,另一个是Person“class”的prototype属性。
  3. 我想没有正确的方式,因为两者都是正确的,但是什么时候我应该更喜欢一种方法而不是另一种?
+2

有一个为每个Person实例创建的'greet'函数,而只有一个'protoGreet'函数,它在所有实例之间共享。 – 2014-10-01 17:43:22

+0

通常,在原型和属性以及构造函数中的受保护方法上编写泛型方法是很方便的。如果所有对象都需要它,请使用proto,如果只有一些做,则在构造函数中进行。 – dandavis 2014-10-01 17:44:06

+1

'Object.create(Person)'应该是'Object.create(Person.prototype)',然后区别在于'Person'构造函数中所做的工作都不会应用到'john'对象,除非你做'Person.call(john,“John”,20,“mars”)' – 2014-10-01 17:44:48

回答

2

和原型功能之间的差异对象本身的功能:
greet函数:此功能(所有功能都是对象)是实例对象的内部,每个实例都有自己的greet函数,你可以看到在图片。

protoGreet功能:位于所述存储器中的独立的对象内部(在图片中的文字对象),而不是由任何Person实例拥有。但是Person的每个实例都有一个隐藏链接(引用)到该对象(此链接称为__proto__)。所以这个对象的Person

enter image description here

所有实例中共享我怎么怎么在意映入眼帘的许多情况有哪些?

内存优化是所有应用程序的本质,实际上对于Web应用程序来说并不存在例外。因此,当单个共享对象适合您的用途时,为每个实例使用单独的对象可能会违反此规则。但是作为性能的观点,第一种方式(即问候函数)可能比第二种方式(即protoGreet函数)更快,因为不会发生称为原型链查找的某个过程。请记住,在这个折衷的记忆是赢家。

对于您的其他问题,似乎你不知道new关键字完成了什么。所以,让我指出一个方面的说明。

注意:这些步骤将在您使用new关键字调用函数时完成。假设我们有以下功能:

function Person (name, age) { 
    this.name = name; 
    this.age = age; 
} 
  • 创建一个空的文本对象即{}(请注意,此对象的隐藏__proto__链接是指由Person.prototype表示的对象)
  • 调用函数和替代所有this关键字与此emply文字对象(在更多技术上,this引用该空文字对象)。
  • 指定的属性和方法将被添加到新创建的对象中。(在这种情况下,nameage属性)。
  • 最后,该对象将隐式地从函数返回。

现在让我们回到你的问题,Object.create(Person.prototype)new Person()之间有什么区别?

上面已经讨论了案例new Person()。但Object.create(Person.prototype)创建一个空对象并将其__proto__链接到第一个输入参数对象(在此例中为Person.prototype),并将该新创建的对象作为输出返回。

好吧,到目前为止,我希望这些说明能够澄清你的问题,但是如果我的答案仍然没有意义,请告诉我你的问题在哪里。

+0

感谢您的回答。你能否参考以下问题? 1.我在乎什么样的问候呢?性能? 2.只有一个特定方法的共享实例有什么好处? 3.在什么情况下,我不需要/不想使用原始构造函数? 4.如果我使用Object.create(Person.prototype)创建对象,那么魔术会发生在哪里?在Object的构造函数中? – undroid 2014-10-02 11:05:39

+0

@undroid请参阅我的更新回答 – 2014-10-02 13:18:10

+0

谢谢!还有些事情不完全清楚。通过文字表达式或new关键字来创建对象,但继承是通过Object.create(Person.prototype)完成的,还是例如'jon = new Person()'?我什么时候比较喜欢使用一种方法? – undroid 2014-10-05 12:18:51