javascript对象原型似乎已被破坏

时间:2016-12-07 02:42:23

标签: javascript prototype

我很困惑为什么我在这里收到此错误。我想要一些启示。



function c(me) { this.me = me; }
c.prototype.identify = function() { return "I am " + this.me; };

function d(me) { c.call(this, me); }
d.prototype = Object.create(c.prototype);
d.prototype.speak = function() { return "Hello, " + this.identify() + "." };

var d1 = new d("d1");
var d2 = new d("d2");

console.log(d1.speak());
console.log(d2.speak());

console.log(d.speak()); //returns: TypeError: d.speak is not a function




  

返回:TypeError:d.speak不是函数

我明确向speak添加了一个属性d.prototype。实际上,d1d2都可以访问其原型层次结构中的属性/函数。然而,当我尝试在d上调用它时,我得到一个TypeError。我尝试过各种各样的调整'无济于事。我试图在IIFE中包装各种部件以试图排除任何范围问题,但它没有任何效果。我从最后一行删除了()

console.log(d.speak);  //returns: undefined

并获取undefined。这告诉我speak不是d有权访问的属性/函数。即。将speak更改为blah并将相同的undefined记录到控制台。

console.log(d.blah);  //returns: undefined

我知道我错过了一些可能对一组新眼睛来说很明显的小事。

2 个答案:

答案 0 :(得分:3)

这是预期的。在大多数情况下,构造函数不是自身的实例。构造函数在prototype中定义实例上可用的方法,但是prototype没有出现在构造函数本身的[[Prototype]]链中。

原因很简单:

  • 一个对象只能有一个[[Prototype]]。

  • 构造函数是一个函数,因此在其[[Prototype]]链中必须有Function.prototype。这允许您在构造函数上调用callapply等函数方法。

  • 实例必须从构造函数的prototype继承,但不能从Function.prototype继承,因为它们不是函数。

因此,通常构造函数不能从其prototype继承。有两个内置例外:FunctionObject

那就是说,你可以选择摆脱上面的第二个或第三个不变量。然后你可以让它工作,但这是一个坏主意,因为通常人们依赖它们,而改变[[Prototype]]会有不好的表现。



function c(me) { this.me = me; }
c.prototype.identify = function() { return "I am " + this.me; };

function d(me) { c.call(this, me); }
d.prototype = Object.create(c.prototype);
d.prototype.speak = function() { return "Hello, " + this.identify() + "." };
Object.setPrototypeOf(d, d.prototype);

var d1 = new d("d1");
var d2 = new d("d2");

console.log(d1.speak()); // "Hello, I am d1."
console.log(d2.speak()); // "Hello, I am d2."
console.log(d.speak()); // "Hello, I am undefined."

console.log(d.call); // undefined    :(






function c(me) { this.me = me; }
c.prototype = Object.create(Function.prototype);
c.prototype.identify = function() { return "I am " + this.me; };

function d(me) { c.call(this, me); }
d.prototype = Object.create(c.prototype);
d.prototype.speak = function() { return "Hello, " + this.identify() + "." };
Object.setPrototypeOf(d, d.prototype);

var d1 = new d("d1");
var d2 = new d("d2");

console.log(d1.speak()); // "Hello, I am d1."
console.log(d2.speak()); // "Hello, I am d2."
console.log(d.speak()); // "Hello, I am undefined."

console.log(d1 instanceof Function); // true    Huh????




答案 1 :(得分:1)

您的变量d构造函数函数。使用该构造函数上的prototype属性访问实例继承的原型对象

console.log(d.prototype.speak) //=> [Function]

演示:

function c(me) { this.me = me; }
c.prototype.identify = function() { return "I am " + this.me; };

function d(me) { c.call(this, me); }
d.prototype = Object.create(c.prototype);
d.prototype.speak = function() { return "Hello, " + this.identify() + "." };

var d1 = new d("d1");
var d2 = new d("d2");

console.log(d1.speak());
console.log(d2.speak());

console.log(d.prototype.speak) //=> [Function]