【问题标题】:Prototype instance like cat c = new animal();?原型实例如 cat c = new animal();?
【发布时间】:2014-04-24 02:32:57
【问题描述】:

我是 Javascript 的新手,最近,我遇到了这个问题,很想知道答案。

function animal(){
  // some bse code
}


function cat(){
  //some cat code
}

// I know this syntax and works well
cat.prototype= new animal;

我想知道下面的语法是否正确?

cat c = new animal;

在javascript中可以吗?

(对不起!如果问题存在。)

【问题讨论】:

  • var c = new cat();好多了!
  • @ius 不!我想知道,cat c 和 cat.prototype 是否相等?
  • TJ 的出色回答。如果您想了解更多关于原型和继承的信息,您可以在这里找到一些有用的信息:stackoverflow.com/a/16063711/1641941

标签: javascript jquery oop prototype


【解决方案1】:

我想知道下面的语法是否正确?

cat c = new animal;

不,JavaScript 变量总是松散类型的,所以你不需要为它们声明类型,你只需用 var 声明它们(在 ES6 中,let)。

所以:

var c = new animal;

附注 #1:在 JavaScript 中,压倒性的约定是对打算用作构造函数的函数使用首字母大写(例如,通过 new 关键字)。例如,AnimalCat,而不是 animalcat


旁注#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");

【讨论】:

  • 在完整的例子中,其实是需要把Cat.prototype.constructor = Cat;?我不明白为什么。
  • @ius:constructor 属性有点奇怪:它是为引擎为函数创建的对象定义的 (§13.2),基本上没有在其他地方提及。为function Foo() { } 创建的Foo.prototype 对象引擎将具有引用Fooconstructor 属性。从理论上讲,这个道具对于克隆对象图很有用,但是那里有很多边缘情况。我总是在替换函数的 prototype obj 时这样做,因为这是规范定义的,否则 constructor 指向错误的函数。
  • 哦,这对我来说是新的!我一直在尝试,你是对的。谢谢!
【解决方案2】:

不,不是。在 JavaScript 中,您不能声明变量的类型。变量的类型就是它当前值的类型,所以

var c = new animal(); //correct

但是

cat c = new animal(); //parse error.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多