JavaScript继承和对象属性

时间:2016-01-06 15:35:02

标签: javascript node.js

我自学了JavaScript,但我对JavaScript中的整个原型设计和继承感到困惑。

示例1:

$auth = $this->get('auth');

这是最容易理解的。 MyClass2的原型是一个MyClass对象,所以class2有权访问它的属性。

示例2:

我想知道是否可以在构造函数本身中设置原型:

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
}

MyClass2.prototype = new MyClass();

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

然而,这似乎并不奏效。 my_var似乎未定义。

示例3:

让我们尝试另一种方法,这次使用Object.create():

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
    this.prototype = new MyClass();
}

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

也没有运气,my_var似乎未定义。

示例4:

这一次,我使用NodeJS"继承()"功能来自" util"模块:

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
}

MyClass2.prototype = Object.create(MyClass);

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

我理解为什么示例1有效,但我不明白为什么2,3和4不能。我希望有人能解释我为什么会这样。

2 个答案:

答案 0 :(得分:1)

示例2: this关键字是对象实例的引用。这是使用new创建的对象。您无法在构造函数中设置原型,因为在使用prototype关键字时,对象的new将用作创建新对象的原型。所以... MyClass的原型在创建新对象时使用,而this引用了instanceof MyClass的某个对象。

.prototype属性是特定于函数的,它是一个复制到该函数/类的实例对象的对象。

示例3: Object.create()从另一个对象创建对象,并传入可能是对象的函数,但不能克隆对象而是函数对象。但是你想要的对象是一个函数/类的实例。

因此,如果您输入:Object.create(MyClass).__proto__,您会看到它是一个功能。 __proto__是在评估脚本后表示的特殊内部对象原型。您可以操纵实验但不建议在生产中操纵它。您可以使用new MyClass修复此示例。

示例4: 您需要在MyClass.call(this);函数中添加MyClass2作为第一行。

答案 1 :(得分:0)

第一个实际上是错误的,因为你应该继承MyClass原型,而不是从它的实例继承。虽然这通常是在过去完成的,但它是一个破坏的继承模型,它希望您在从它派生子类之前创建一个类的实例。

从那以后,其他示例也是错误的,因为在每种情况下,您仍然从一个实例继承(在第二和第三种情况下)或者期望基类的非原型属性可见在派生类中(案例四)。

案例三的正确表述是:

function MyClass() {
}

MyClass.prototype.myMethod = function() { ... }

function MyClass2() {
    MyClass.call(this);     // invoke superclass constructor
}

// create a new (empty) prototype that chains to the superclass's
MyClass2.prototype = Object.create(MyClass.prototype);

// and reattach the constructor
MyClass2.prototype.constructor = MyClass2;

// now add methods to MyClass2
MyClass2.prototype.myMethod2 = function() { ... }