2015-03-02 81 views
0

这工作设置原型:使用Javascript - 从内部功能

function Bird(name){ 
    Animal.call(this,name); 
    this.speak = function(){ 
     console.log("Tweeet!"); 
    } 
} 
Bird.prototype.constructor = Animal; 

这将引发 “无法设置属性未定义的构造函数”“

function Bird(name){ 
    Animal.call(this,name); 
    this.speak = function(){ 
     console.log("Tweeet!"); 
    } 
    this.prototype.constructor = Animal; 
} 

为什么会是这样?在第二个例子中,应该因为我已经调用的函数与,所以我应该能够设置原型。我在这里错过了什么?

+2

'this'内部功能 - 对象,因此它不具有原型财产,但如果你将'this'改为'Bird'都应该可以工作 – Grundy 2015-03-02 10:08:41

+0

只是回答我自己的问题,现在我理解JavaScript更好一些。在第二个示例中,'this'不是'Bird' - 'this'是已创建并传递给Bird函数的新对象。 – wagster 2015-09-30 08:14:50

回答

2

Object实例(this)没有prototype属性,所以this.prototype返回undefined

你有两个选择来解决这个问题:

  1. 呼叫Bird.prototype,你在第一个片段那样:

    function Bird(name){ 
        Animal.call(this,name); 
        this.speak = function(){ 
         console.log("Tweeet!"); 
        } 
        Bird.prototype.constructor = Animal; 
    } 
    
  2. 使用Object.getPrototypeOf来获取对象的原型的保持:

    function Bird(name){ 
        Animal.call(this,name); 
        this.speak = function(){ 
         console.log("Tweeet!"); 
        } 
        Object.getPrototypeOf(this).constructor = Animal; 
    } 
    

当您不知道对象是什么类型时,选项2更有用。在你的例子中,你在Bird类中,所以选项1更有意义。


这里是一个工作示例,希望这将使得这个问题在您的评论更清晰:

// 1. Tell Javascript what an Animal is 
 
// This will create an Object called Animal, but it is a blueprint not an actual Animal. 
 

 
function Animal(name) 
 
{ 
 
    this.name = name; 
 
} 
 

 
// 2. Tell Javascript what a Bird is 
 
// This will create an Object called Bird, but it is a blueprint not an actual Bird. So it cannot speak! 
 

 
// or function Bird(name){ 
 
var Bird = function(name){ 
 
    Animal.call(this,name); 
 
    this.speak = function(){ 
 
     alert("Tweeet! said " + this.name); 
 
    } 
 
    
 
    Object.getPrototypeOf(this).constructor = Animal; 
 
}; 
 

 
// 3. Now create an actual Bird which can speak 
 

 
var tweety = new Bird("Tweety Pie"); 
 
tweety.speak();

+0

感谢Rhumborl。我想我可能会误解功能如何工作。这是我认为它的工作原理:由于JS没有类,当我定义**函数Bird(){} **时,该函数在当前上下文中被实例化为对象。我错了吗?可以存在一个不是实例化对象的函数吗? – wagster 2015-03-02 10:51:22

+0

@wagster尝试查看[new operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new)。当你定义函数 - 你定义函数,当你实例化对象时 - 你实例化对象 – Grundy 2015-03-02 10:58:21

+0

@wagster是的你说的听起来是正确的,但是你可能混合了对象的类型。在JS中,_everything_是一个对象,包括函数,所以函数Bird(){}'将在当前作用域中创建一个名称为“Bird”的类型为“Function”的对象。实际上为了让它更清晰,你可以把它写成'var Bird = function(){}'。此时,没有鸟实际存在,你刚刚告诉JS如何创建一个鸟。如果你想要一个实际的“鸟”,你需要使用'var canary = new Bird(“Tweety Pie”)''。这是_this_调用,它将实际运行你的'Bird'方法并给你一个'Bird'类型的对象。 – Rhumborl 2015-03-02 11:05:21