我自学了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不能。我希望有人能解释我为什么会这样。
答案 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() { ... }