PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!
后面两章中提到的实现继承的方法,都是《Object-Oriented JavaScript》第六章说起的,书中最后也做了总结:
In this chapter you learned quite a few ways (patterns) for implementing inheritance.
The different types can roughly be divided into:
- Patterns that work with constructors
- Patterns that work with objects
You can also classify the patterns based on whether they:
- Use the prototype
- Copy properties
- Do both (copy properties of the prototype)
第六章介绍了一些继承的方法,分为两模式:
基于构造函数生成对象的模式
直接继承对象的模式
也可以按照另一种思路分类:
应用了原型prototype
复制属性
复制原型的属性
可以说,这是实现继承的最核心的内容,实践中常常交织在一起。回顾下前文介绍的基本继承方法:
//构造函数 应用原型链
Coder.prototype = new Person("无名");
//构造函数 同享原型链 Coder.prototype = Person.prototype;
//构造函数 应用原型链 只继承原型属性方法 function extend(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
//构造函数 应用原型链 复制原型属性 function extend2(Child,Parent){ var p = Parent.prototype; var c = Child.prototype; for(var i in p){ c[i] = p[i]; } }
//继承对象 复制属性 function extendCopy(p, c){ var c = c || {}; for(var i in p){ c[i]=p[i]; } return c; }
//继承对象 深复制 function deepCopy(){}
//继承对象 应用原型链 function object(o){ function F(){}; F.prototype = o; return new F(); }
//继承对象 应用原型链 复制属性 function objectPlus(o, stuff){}
//继承对象 复制属性 function multi(){}
遗留的一些事件
1.之前的文章中出现以下代码
function Person(name){ this.name = name; } Person.prototype.sayHello = function(){ alert(this.name); }; function Coder(name,language){ this.language = language; this.name = name; } Coder.prototype = new Person("无名"); Coder.prototype.constructor = Coder; Coder.prototype.code = function(){ alert("i am a "+this.language+" coder"); };
function Person(name){ this.name = name; } Person.prototype.sayHello = function(){ alert(this.name); }; function Coder(name,language){ Person.apply(this,arguments); this.language = language; } extend2(Coder,Person); Coder.prototype.code = function(){ alert("i am a "+this.language+" coder"); };
如果扩展的原型方法很多,我想你一定有办法知道如果通过之前的基础方法,写出一个新的符合你自己要求的继承机制。
我们完全可以写一个 extend3(Coder,Person,stuff)的方法~如果你有须要这么做的话。
2.几个函数操作
obj instanceof F // 判断对象obj是否是F的实例
F.prototype.isPrototypeOf(obj)//作用同上
obj.constructor // 返回obj的构造函数
obj.hasOwnProperty('属性名') // 判断obj是否有属于自己的属性,而不是他所指原型的属性
这几个操作帮助懂得原型链、继承过程,在实践中也有很重要的作用。
3.关于 子“类”调用父"类"的方法、属性
有三个类 Shape TwoDShape Triangle 形状、2D形状、三角形,他们继承关系。
对象实例须要实现一种方法:toString() 不仅要输出自己的类名,还要输出祖辈的类名。
如何实现呢?
由于继承的实现方法挺多的,而且子“类”的这种需求变幻无穷,如何有效控制,文章(本人能力无限)一句话说不清楚,《o-o》中也只是交叉地说了一下。
基本的一种思路是 在 Parent加一个静态属性uber指向Child.prototype
function extend(Child,Parent){ var F = function(){}; F.prototype = Parent.prototype; Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
function Shape(){}; Shape.ptototype.name = "shape"; Shape.prototype.toString = function(){ var result = []; if(this.constructor.uber){ result[result.length] = this.constructor.uber.toString(); } result[result.length] = this.name; return result.join(', '); }; function TwoDShape(){}; extend(TwoDShape,Shape); TwoDshape.prototype.name = "2dShape"; function Triangle(side, height){ this.side = side; this.height = height; }; extend(Triangle, TwoDShape); Triangle.prototype.name = "triangle"; Triangle.prototype.getArea = function(){return this.side*this.height/2;}; var my = new Triangle(3,4); my.toString();
function extend2(Child,Parent){ var p = Parent.prototype; var c = Child.prototype; for(var i in p){ c[i] = p[i]; } c.uber = p; }
对象直接继承的时候
function object(o){ var n; function F(){} F.prototype = o; n = new F(); n.uber = o; return n; }
下面的实现 都是 《o-o》第六章中说起的
实例、原型、构造函数 谁可以最直接地调用方法uber ,以及要发生什么效果,按需实现。
uber 是源于德语,super是js中的一个关键词,因此建议应用uber
到此,《o-o》第六章的内容都介绍完毕,内容基于自己的梳理,增加了自己的懂得,难免有疏漏的地方,请教正。
欢迎大家看原著,国内也出了翻译版~
文章结束给大家分享下程序员的一些笑话语录: 苹果与谷歌之争就是封闭收费与自由免费思想之争。(别急着把google来膜拜哦?那可是一家公司,以赚钱为目标的公司!当年我Party就是这样把广大劳动人民吸引过来的。今天的结果你们都看到了。)