我想知道下面的语法是否正确?
cat c = new animal;
不,JavaScript 变量总是松散类型的,所以你不需要为它们声明类型,你只需用 var 声明它们(在 ES6 中,let)。
所以:
var c = new animal;
附注 #1:在 JavaScript 中,压倒性的约定是对打算用作构造函数的函数使用首字母大写(例如,通过 new 关键字)。例如,Animal 和 Cat,而不是 animal 和 cat。
旁注#2:关于这个:
// I know this syntax and works well
cat.prototype= new animal;
这是一种常见但较差的做法。以下是如何正确执行此操作:
cat.prototype = Object.create(animal.prototype);
cat.prototype.constructor = cat;
...然后在cat,作为第一件事:
animal.call(this);
更新大写的完整示例:
function Animal() {
}
function Cat() {
Animal.call(this);
// ...add Cat-level initialization here
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
关于Object.create:它是一个 ES5 函数,它创建一个具有特定底层原型的对象。正确的 ES5 版本需要两个参数,而它对第二个参数的作用不能在旧浏览器上进行填充。但是对于我们正在做的事情,我们只需要第一个参数,可以在旧浏览器上填充:
if (!Object.create) {
Object.create = function(proto, props) {
if (typeof props !== "undefined") {
throw "Object.create shims cannot implement the second argument.";
}
function ctor() { }
ctor.prototype = proto;
return new ctor();
};
}
那么为什么Cat.prototype = new Animal; 实践不佳?那么,如果Animal 接受每个实例的参数怎么办?考虑:
function Animal(age) {
this.age = age;
}
我们会在Cat.prototype = new Animal(???); 行中为age 提供什么?
回答:我们没有。在构造实例之前,我们不应该调用Animal,它是实例的构造函数。相反,我们为Cat.prototype 属性创建一个新对象,并将该新对象Animal.prototype 作为其原型。
完整示例:
function Animal(age) {
this.age = age;
}
function Cat(age, color) {
Animal.call(this, age);
this.color = color;
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
var c = new Cat(14, "Tabby");