JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6777字,纯文字阅读大概需要10分钟。
内容图文
![JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance](/upload/InfoBanner/zyjiaocheng/1231/196cc31ec0194acab832abcc5c7d32ae.jpg)
// the parent constructor function Parent(name) { this.name = name || ‘Adam‘; } // adding functionality to the prototype Parent.prototype.say = function () { returnthis.name; }; // empty child constructorfunction Child(name) {} inherit(Child, Parent);
A method say() added to the parent constructor’s prototype, and a call to a function called inherit() that takes care of the inheritance. The inherit() function is not provided by the language, so you have to implement it yourself.
Classical Pattern #1—The Default Pattern
Create an object using the Parent() constructor and assign this object to the Child()’s prototype.
function inherit(C, P) { C.prototype = new P(); } var kid = new Child(); kid.say(); // "Adam"
- Following the Prototype Chain
- Drawbacks when Using Pattern #1
- Inherit both own properties added to this and prototype properties.
Note: reusable members should be added to the prototype.
- It doesn‘t enable you to pass parameters to child constructor, which the child then passes to the parent.
Classical Pattern #2 -- Rent-a-Constructor
Passing arguments from the child to the parent.
function Child(a, c, b, d) { Parent.apply( this , arguments); } // a parent constructor function Article() { this.tags = [‘js‘, ‘css‘]; } var article = new Article(); // a blog post inherits from an article object// via the classical pattern #1function BlogPost() {} BlogPost.prototype = article; var blog = new BlogPost(); // note that above you didn‘t need `new Article()`// because you already had an instance available// a static page inherits from article// via the rented constructor patternfunction StaticPage() { Article.call(this); } var page = new StaticPage(); alert(article.hasOwnProperty(‘tags‘)); // true alert(blog.hasOwnProperty(‘tags‘)); // false alert(page.hasOwnProperty(‘tags‘)); // true
- The Prototype Chain
The inheritance was a one-off action that copied parent’s own properties as child’s own properties and that was about it; no __proto__ links were kept.
// the parent constructor function Parent(name) { this.name = name || ‘Adam‘; } // adding functionality to the prototype Parent.prototype.say = function () { returnthis.name; }; // child constructorfunction Child(name) { Parent.apply(this, arguments); } function showMsg(msg) { $(‘#msg‘).append(msg).append(‘<br/>‘); } $(function () { var kid = new Child("Patrick"); showMsg(kid.name); // "Patrick" showMsg(typeof kid.say); // "undefined" });
- Multiple Inheritance by Borrowing constructors
Implement multiple inheritance simply by borrowing from more than one constructor
function Cat() { this.legs = 4; this.say = function () { return "meaowww"; } } function Bird() { this.wings = 2; this.fly = true; } function CatWings() { Cat.apply(this); Bird.apply(this); } var jane = new CatWings(); console.dir(jane);
- Pros and Cons of the Borrowing Constructor Pattern
Pros: Get true copies of the parent‘s own members and there‘s no risk that a child can accidentally overwrite a parent‘s property.
Cons: Nothing from the prototype gets inherited.
Classical Pattern #3—Rent and Set Prototype
function Child(a, c, b, d) { Parent.apply( this , arguments); } Child.prototype = new Parent();
The benefit is that the result objects get copies of the parent’s own members and references to the parent’s reusable functionality (implemented as members of the prototype). The child can also pass any arguments to the parent constructor. This behavior is probably the closest to what you’d expect in Java; you inherit everything there is in the parent, and at the same time it’s safe to modify own properties without the risk of modifying the parent.
A drawback is that the parent constructor is called twice, so it could be inefficient. At the end, the own properties (such as name in our case) get inherited twice.
// the parent constructor function Parent(name) { this.name = name || ‘Adam‘; } // adding functionality to the prototype Parent.prototype.say = function () { returnthis.name; }; // child constructorfunction Child(name) { Parent.apply(this, arguments); } Child.prototype = new Parent(); function showMsg(msg) { $(‘#msg‘).append(msg).append(‘<br/>‘); } var kid = new Child("Patrick"); kid.name; // "Patrick" kid.say(); // "Patrick"delete kid.name; kid.say(); // "Adam"
Classical Pattern #4—Share the Prototype
This gives you short and fast prototype chain lookups because all objects actually share the same prototype.
function inherit(C, P) { C.prototype = P.prototype; }
Drawback
if one child or grandchild somewhere down the inheritance chain modifies the prototype, it affects all parents and grandparents.
Classical Pattern #5—A Temporary Constructor
An empty function F(), which serves as a proxy between the child and the parent. F()’s prototype property points to the prototype of the parent. The prototype of the child is an instance of the blank function:
function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); }
In this pattern, any members that the parent constructor adds to this are not inherited.
- Storing the Superclass
The property is called uber because “super” is a reserved word and “superclass” may
lead the unsuspecting developer down the path of thinking that JavaScript has classes.
Here’s an improved implementation of this classical pattern:
function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; }
- Resetting the Constructor Pointer
If you don’t reset the pointer to the constructor, then all children objects will report that Parent() was their constructor, which is not useful.
// parent, child, inheritance function Parent() {} function Child() {} inherit(Child, Parent); // testing the waters var kid = new Child(); kid.constructor.name; // "Parent" kid.constructor === Parent; // truefunction inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; }
Create temporary (proxy) constructor once and only change its prototype. You can use an immediate function and store the proxy function in its closure:
var inherit = (function () { // This will only be executed once which means only one function object is created for every inheritance.var F = function () {}; returnfunction (C, P) { F.prototype = P.prototype; // F.prototype.constructor is pointed to Parent. C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; } }());
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
原文:http://www.cnblogs.com/haokaibo/p/Expected-Outcome-When-Using-Classical-Inheritance.html
内容总结
以上是互联网集市为您收集整理的JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance全部内容,希望文章能够帮你解决JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。