为什么没有将方法添加到原型中会产生错误"未定义"?

时间:2014-06-06 02:35:39

标签: javascript prototype prototypal-inheritance

我不了解原型。据我所知,这段代码应该可行。我使用Object.create创建了一个原型,并为原型添加了一个方法,但我一直收到错误。那么如何让这段代码正常工作呢?让我重新说一下,如何正确编写代码?

// base function
function person()
{
    this.name;
    this.type;
}

//create instance of function
var a = new person();
a.name = 'ha';
console.log(a.name);

//as opposed to creating instance like above, have new object "b" have the function person as its prototype
var b = Object.create(person);
b.name = 'ho';
console.log(b.name);

//add the method height to the prototype, aka. underlying object "person"
b.prototype.height = function(h) {return h * 2;};

console.log(b.height(5));

//scratch head and ask SO why this doesn't work
/*
Exception: b.height is not a function
@Scratchpad/3:26
*/

2 个答案:

答案 0 :(得分:1)

//as opposed to creating instance like above, have new object "b" have the 
//function person as its constructor, person.prototype as its prototype object
var b = Object.create(person); //this is wrong
var b = Object.create(person.prototype); //this is right. b now has person() as its constructor

Object.create()方法使用指定的原型对象和属性创建一个新对象。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

//this wouldnt work because b is an object, not a constructor. 
//If you want b to inherit the height method, define it on the it's constructor's
//prototype object which is person.prototype 
//(NOTE that you created b from person.prototype)
person.prototype.height = function(h) {return h * 2;};  

答案 1 :(得分:1)

//as opposed to creating instance like above, have new object "b" have the function person as its prototype
var b = Object.create(person);

是的,这正是发生的事情:您将 Function 对象作为原型。而这不是你想要的! new operator确实创建了从构造函数的.prototype对象继承的实例。因此,如果要使用Object.create手动实例化对象,则需要编写

var b = Object.create(person.prototype);
// and you might do `person.apply(b)` to invoke the constructor

顺便说一句,您的b.prototype.height = function(h){…}a实例的效果很好,您可以调用console.log(a.height(5))


但是,由于您的构造函数没有执行任何操作,因此您可以完全省略它。没有构造函数(及其.prototype属性),您可以像这样进行纯粹的原型继承:

var person = { // the prototype object for all persons
    height: function(h) {return h * 2;}
};

var a = Object.create(person);
a.name = 'ha';

// adding methods to all persons:
person.logName = function() { console.log(this.name); };
a.logName();

相反,典型的构造函数+ .prototype方法如下所示:

function Person(name) { // constructors are capitalized
    this.name = name;
}
Person.prototype.height = function(h) {return h * 2;};

var a = new Person('ha');

// adding methods to all Persons:
Person.prototype.logName = function() { console.log(this.name); };
a.logName();