【问题标题】:JavaScript Inheritance assigning a value to constructorJavaScript 继承给构造函数赋值
【发布时间】:2016-08-09 19:17:02
【问题描述】:

我正在学习 javascript OOP,但在理解继承时遇到了问题。你能解释一下为什么这两个代码的结果不同吗? :

代码 1

function a(){}

function b(){
    this.uno = "hello"}

b.prototype = new a();

function c(){
    this.dos = "bye"}

c.prototype= new b();

var obj = new c();

console.log(obj.uno);
console.log(obj.dos);
console.log(obj.constructor);

输出 1

hello 
bye
[function: a]

代码 2

function a(){}


function b(){
    this.uno = "hola"}


b.prototype = new a();


function c(){
    this.dos = "bye"}

c.prototype = {constructor:b}

var obj = new c();

console.log(obj.uno);
console.log(obj.dos);
console.log(obj.constructor);

输出 2

undefined
bye
[function: b]

我非常感谢任何有关该主题的指南。

【问题讨论】:

  • 不同是因为new b()不返回{constructor:b},所以不是一回事
  • 问题是:为什么您期望它们的行为完全相同?它们明显不同。
  • 即使你将一个对象分配给它自己的原型也没有任何意义。
  • 我之前关于类似主题的答案之一是stackoverflow.com/a/38819813/5102631。它也说明了类似的问题。 @max 你也可以检查一下。
  • constructor 属性对 Javascript 中的原型继承没有任何影响,除非您的代码明确使用它。这个question/answer 可能会有所帮助。

标签: javascript inheritance constructor prototype


【解决方案1】:

在代码sn-p中

function a() {}

function b() {
  this.uno = "hello"
}

b.prototype = new a();

function c() {
  this.dos = "bye"
}

c.prototype = new b();

var obj = new c();

console.log(obj.uno);
console.log(obj.dos);
console.log(obj.constructor);

让我们了解发生了什么。当你在做

b.prototype = new a();

a 的新实例被创建并直接分配给b 的原型。 所以现在如果有人这样做 var obj = new b(); obj.uno 将等于 hello

现在,当声明

c.prototype = new b();

执行后,obj(b 类的实例)现在分配给 c 的原型。所以现在如果有人这样做 var obj = new c();

  • obj.dos = byec 构造函数类中分配。
  • obj.uno = 'hello',因为它曾经在实例化 b 构造函数时被赋值。
  • 由于没有重新分配构造函数属性,它仍将指向原始父级a。所以obj.constructor = function a()

在第二个sn-p

function a() {}


function b() {
  this.uno = "hola"
}


b.prototype = new a();


function c() {
  this.dos = "bye"
}

c.prototype = {
  constructor: b
}

var obj = new c();

console.log(obj.uno);
console.log(obj.dos);
console.log(obj.constructor);

c.prototype = { 构造函数:b }

没有继承b 或其原型链。在每个构造函数s prototype chain there is aconstructorproperty which points to the constructor class. In the avobe statement, it just reassings it to the functionb`。

更新: Constructor 是在任何对象的原型链中定义的属性,因为函数在 JS 中是 first-class-objects,它们也有这个属性。

因此,当您执行上述行时,它基本上会更改 c.prototype.constructor 的值。仅此而已。

你有没有这样做过

 c.prototype = {
  constructor: 5
}
...
console.log(obj.constructor); // 5.
//Its like setting a value for a property in a JS object.

所以当你这样做时:

console.log(obj.constructor);

它指向新分配的构造函数,即function b()

但由于没有继承,

console.log(obj.uno);

肯定是未定义的。

然而,

console.log(obj.dos);

当您创建函数 c 的新实例时,将是 bye

var obj = new c();

希望这有助于更好地理解 JS 原型继承。

【讨论】:

  • 非常感谢您的热心回答Ayan。我认为原型对象的属性“构造函数”负责函数类的继承。那么,您说 c.prototype = { constructor: b } 不是继承而是重新分配是什么意思?
  • 嘿@maxfraguas 已经更新了答案的那一部分,并举了一个例子。让我知道它是否听起来更好
【解决方案2】:

因为new b() !== {constructor:b} (as adeneo mentioned)。原型需要 a lot more 而不仅仅是 {constructor} 属性,因此仅提供一个对象(字面量)并没有多大作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    相关资源
    最近更新 更多