[英]JavaScript prototype-Object - how to access inheritance
At the moment, I try to understand the Javascript prototype object. 目前,我尝试了解Javascript原型对象。 Following situation:
以下情况:
// new Person object
function Person () {
this.greeth = function() {
console.log("Good morning, " + this.name);
};
};
// add new function to Person.prototype for inheritance
Person.prototype.sayWeight = function() {
console.log(this.weight);
};
// create new friend object
var friend = {
forename: "Bill",
lastname: "Gates",
weight: 78,
sayhello: function() {
console.dir("Hello " + this.forename + ' ' + this.lastname);
}
};
// assign Person.prototype to friend.prototye (inheritance)
friend.prototype = Person;
console.dir(friend);
Now my question: I assign the Person Object to my friend.prototype
. 现在我的问题是:我将Person对象分配给我的
friend.prototype
。 For my understanding, " friend
" should have all the functions of Person.prototype
(ie sayWeight()
cause of friend.prototype = Person;
). 就我的理解而言,“
friend
”应该具有Person.prototype
所有功能(即sayWeight()
原因是friend.prototype = Person;
)。 But the only function I can call is friend.sayhello. 但是我唯一可以调用的功能是friend.sayhello。 In my output (
console.dir(friend);
), I can see the sayWeight()
function, but when I call it, I get an error ( TypeError: Object #<Object> has no method 'sayWeight'
) 在我的输出中(
console.dir(friend);
),我可以看到sayWeight()
函数,但是当我调用它时,我得到了一个错误( TypeError: Object #<Object> has no method 'sayWeight'
)
Can you explain this behavior? 你能解释这种行为吗? Why can't I access the
sayWeight()
function? 为什么不能访问
sayWeight()
函数?
========================================================= ================================================== =======
Another question: 另一个问题:
function Person() {
this.name = "Bill Gates";
this.weight = 78;
this.sayHello = function() {
console.log("Hello " + this.name);
}
}
Person.prototype.sayWeight = function() {
console.log(this.weight);
}
var friend = new Person();
What is the difference between the sayWeight
and the sayHello
function? sayWeight
和sayHello
函数之间有什么区别? The sayWeight
function is in the prototype-object of Person - okay, but what advantages do I have from prototype in this case? sayWeight
函数位于Person的原型对象中-好的,但是在这种情况下,我可以从原型中获得什么好处?
Can you explain this behavior?
你能解释这种行为吗? Why can't I access the sayWeight() function?
为什么不能访问sayWeight()函数?
Because you can't change the prototype of an object after you create it. 因为创建对象后无法更改其原型。 You are setting the prototype property, but the internal prototype reference that is used by the javascript interpreter, namely
__proto__
is still the one used in effect, and currently __proto__
is referring to Object.prototype
. 您正在设置prototype属性,但是javascript解释器使用的内部原型引用(即
__proto__
)仍然有效,当前__proto__
引用的是Object.prototype
。
If you changed this line friend.prototype = Person;
如果您更改此行,
friend.prototype = Person;
to this one friend.__proto__ = Person.prototype;
friend.__proto__ = Person.prototype;
then everything will work. 然后一切都会正常。
If your browser supports ES5 then you can use Object.create()
to create objects that inherit from a given prototype, or you can use a workaround adopted from the book Javascript: The Good Parts, and twisted a little by David Flanagan in his book: Javascript The Definitive Guide: 如果您的浏览器支持ES5,则可以使用
Object.create()
创建从给定原型继承的对象,或者可以使用Javascript:The Good Parts一书中的变通方法,并在David Flanagan的书中稍作改动:Javascript权威指南:
// inherit() returns a newly created object that inherits properties from the
// prototype object p. It uses the ECMAScript 5 function Object.create() if
// it is defined, and otherwise falls back to an older technique.
function inherit(p) {
if (p == null) throw TypeError(); // p must be a non-null object
if (Object.create) // If Object.create() is defined...
return Object.create(p); // then just use it.
var t = typeof p; // Otherwise do some more type checking
if (t !== "object" && t !== "function") throw TypeError();
function f() {}; // Define a dummy constructor function.
f.prototype = p; // Set its prototype property to p.
return new f(); // Use f() to create an "heir" of p.
}
NOTE __proto__
isn't a standardized property and shouldn't be used in production code, or as @alex noted in his comment it is on the way of standardization. 注意
__proto__
不是标准化的属性,不应在生产代码中使用,或者正如@alex在其评论中指出的那样,这是标准化的方式。
NOTE 2: As @thg435 mentioned in his comment, an alternative to using the __proto__
property is using Object.setPrototypeOf()
which is standardized in ES6. 注意2:正如@ thg435在他的评论中提到的,使用
__proto__
属性的另一种方法是使用ES.6中标准化的Object.setPrototypeOf()
。
What is the difference between the sayWeight and the sayHello function ?
sayWeight和sayHello函数之间有什么区别?
The difference is that now each new instance of Person
(for example new Person()
) will have a distinct sayHello()
function, but a shared sayWeight()
function. 区别在于,现在每个新的
Person
实例(例如new Person()
)将具有不同的sayHello()
函数,但具有共享的sayWeight()
函数。
var friend = new Person();
var anotherFriend = new Person();
console.log(friend.sayHello === anotherFriend.sayHello); // OUTPUTS FALSE
console.log(friend.sayWeight === anotherFriend.sayWeight); // OUTPUTS TRUE
what advantages do I have from prototype in this case?
在这种情况下,我从原型有什么优势?
Well less memory, code reuse across all instances of person, and if you already have one or more person objects and you want to add a new method to all of them without modifying each one in turn then you can add that method to the prototype and they will all inherit from it. 更少的内存,代码可以在人员的所有实例之间重用,并且如果您已经有一个或多个人员对象,并且想要向所有对象添加新方法而又不依次修改每个对象,则可以将该方法添加到原型中他们都会从中继承。
Person
doesn't inherit Person.prototype
, only instances of Person
do. Person
不继承Person.prototype
,仅继承Person
实例。 Further, with a normal Object say foo = {}
, foo.prototype
is just a normal property. 此外,使用普通对象说
foo = {}
, foo.prototype
只是普通属性。 You'd either need a constructor or to create the initial object defining it as having a specific prototype. 您将需要构造函数或创建将其定义为具有特定原型的初始对象。
What you actually want is 你真正想要的是
friend = Object.create(Person.prototype);
// or, for older browsers
friend = new Person();
// or some Object.create shim
/* which gives you
friend inherits Person.prototype
inherits Object.prototype */
This sets up the prototype chain. 这样就建立了原型链。 If you want to create many friends, it may be better to set up a new constructor
Friend
, which has Friend.prototype = Object.create(Person.prototype);
如果要创建很多朋友,最好设置一个新的构造函数
Friend
,它的Friend.prototype = Object.create(Person.prototype);
. 。 This also protects
Person.prototype
from if you want to add properties to Friend.prototype
. 这也保护
Person.prototype
距离,如果你想添加属性Friend.prototype
。 Then you would have 那你就会有
(instanceof) Friend inherits Friend.prototype
inherits Person.prototype
inherits Object.prototype
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.