读《JavaScript面向对象编程指南》(二)

第五章 原型

  • 在JavaScript中,所有函数都会拥有一个 prototype 的属性,默认初始值为空对象。 
  • 可以在相关的原型对象中添加新的方法和属性,甚至可以用自定义对象来完全替换掉原有的原型对象。
  • 通过某个构造器函数来new一个对象时,这些对象就会自动拥有一个指向 prototype 属性的 __proto__链接,通过它可以访问相关原型对象的属性。
  • 对象自身属性的优先级要高于其原型对象的同名属性。
  • 扩展内建对象不是一个好主意,如果必须要采用的话一定要谨慎。
  • 当我们对原型对象执行完全替换时,可能会触发原型链某种异常,prototype.constructor属性是不可靠的。
  • Best Practice:当我们重写某对象的prototype时,重置相应的constructor属性是一个好习惯。
  • 每个对象都会有一个isprototype()方法,这个方法会告诉我们当前对象是否是另一个对象的原型。
  • 神秘的__proto__链接。

    枚举属性

      

      

     

     

参考链接:JavaScript for...in循环

第六章 继承

  1 //6.1.1 原型链示例
  2 //6.1.2 将共享属性迁移到原型中去
  3 //6.2   只继承于原型 
  4 function Shape(){
  5 
  6 }
  7 Shape.prototype.name = 'shape';
  8 Shape.prototype.toString = function(){
  9     return this.name;
 10 }
 11 function TwoDShape(){
 12 
 13 }
 14 TwoDShape.prototype = Shape.prototype;
 15 TwoDShape.prototype.constructor = TwoDShape;
 16 TwoDShape.prototype.name = '2D shape';
 17 
 18 function Triangle(side, height){
 19     this.side = side;
 20     this.height = height;
 21 }
 22 Triangle.prototype = TwoDShape.prototype;
 23 Triangle.prototype.constructor = Triangle;
 24 Triangle.prototype.name = 'Triangle';
 25 Triangle.prototype.getArea = function(){
 26     return this.side * this.height / 2;
 27 }
 28 //临时构造器  new F()
 29 function Shape(){
 30 
 31 }
 32 Shape.prototype.name = 'shape';
 33 Shape.prototype.toString = function(){
 34     return this.name;
 35 }
 36 function TwoDShape(){
 37 
 38 }
 39 var F = function(){};
 40 F.prototype = Shape.prototype;
 41 TwoDShape.prototype = new F();
 42 TwoDShape.prototype.constructor = TwoDShape;
 43 TwoDShape.prototype.name = '2D shape';
 44 
 45 function Triangle(side, height){
 46     this.side = side;
 47     this.height = height;
 48 }
 49 var F = function(){};
 50 F.prototype = TwoDShape.prototype;
 51 Triangle.prototype = new F();
 52 Triangle.prototype.constructor = Triangle;
 53 Triangle.prototype.name = 'Triangle';
 54 Triangle.prototype.getArea = function(){
 55     return this.side * this.height / 2;
 56 }
 57 
 58 //6.3 uber——子对象访问父对象的方式
 59 function Shape(){}
 60 Shape.prototype.name = 'shape';
 61 Shape.prototype.toString = function(){
 62     var result = [];
 63     if (this.constructor.uber){
 64         result[result.length] = this.constructor.uber.toString();
 65     }
 66     result[result.length] = this.name;
 67     return result.join(', ');
 68 }
 69 function TwoDShape(){
 70 
 71 }
 72 var F = function(){};
 73 F.prototype = Shape.prototype;
 74 TwoDShape.prototype = new F();
 75 TwoDShape.prototype.constructor = TwoDShape;
 76 TwoDShape.uber = Shape.prototype;
 77 TwoDShape.prototype.name = '2D shape';
 78 
 79 function Triangle(side, height){
 80     this.side = side;
 81     this.height = height;
 82 }
 83 var F = function(){};
 84 F.prototype = TwoDShape.prototype;
 85 Triangle.prototype = new F();
 86 Triangle.prototype.constructor = Triangle;
 87 Triangle.uber = TwoDShape.prototype;
 88 Triangle.prototype.name = 'Triangle';
 89 Triangle.prototype.getArea = function(){
 90     return this.side * this.height / 2;
 91 }
 92 
 93 // 6.4 将继承部分封装成函数
 94 function extend(Child, Parent){
 95     var F = function(){};
 96     F.prototype = Parent.prototype;
 97     Child.prototype = new F();
 98     Child.prototype.constructor = Child;
 99     Child.uber = Parent.prototype;
100 }
101 extend(TwoDShape, Shape);
102 extend(Triangle, TwoDShape);
103 
104 //6.5 属性拷贝
105 function extend2(Child, Parent){
106     var p = Parent.prototype;
107     var c = Child.prototype;
108     for (var i in p){
109         c[i] = p[i];
110     }
111     c.uber = p;
112 }
113 
114 //6.6 小心处理引用拷贝
115 //6.7 对象之间的继承
116 function extendCopy(p){
117     var c = {};
118     for(var i in p){
119         c[i] = p[i];
120     }
121     c.uber = p;
122     return c;
123 }
124 
125 //6.8 深拷贝
126 function deepCopy(c, p){
127     var c = c || {};
128     for (var i in p){
129         if (typeof p[i] === 'object'){
130             c[i] = (p[i].constructor === Array) ? [] : {};
131             deepCopy(c[i], p[i])
132         }else{
133             c[i] = p[i];
134         }
135     }
136     return c;
137 }
138 //6.9 object(),Douglas Crockford为我们提出了一个建议,既可以用object()
139 //函数来接受父对象,并返回一个以该对象为原型的新对象。
140 function object()(o){
141     var n;
142     function F(){}
143     F.prototype = o;
144     n = new F();
145     n.uber = o;
146     return n;
147 }
148 
149 //6.10 原型继承于属性拷贝的混合使用
150 function objectPlus(o, stuff){
151     var n;
152     function F(){};
153     F.prototype = o;
154     n = new F();
155     n.uber = o;
156 
157     for(var i in stuff){
158         n[i] = stuff[i];
159     }
160     return n;
161 }
162 
163 //6.11 多重继承
164 function multi(){
165     var n = {}, stuff, j = 0, len = arguments.length;
166     for(j = 0; j < len; j++){
167         stuff = arguments[j];
168         for(var i in stuff){
169             n[i] = stuff[i];
170         }
171     }
172     return n;
173 }
174 
175 //6.12 寄生式继承
176 var twoD = {
177     name : '2D shape',
178     dimensions : 2
179 }
180 function triangle(s, h){
181     var that = object(twoD);
182     that.name = 'Triangle';
183     that.getArea = function(){
184         return this.side * this.height / 2
185     };
186     that.side = s;
187     that.height = h;
188     return that;
189 }
190 
191 //6.13 构造器借用
192 function Shape(id){
193     this.id = id;
194 }
195 Shape.prototype.name = 'shape';
196 Shape.prototype.toString = function(){
197     return this.name;
198 }
199 function Triangle(){
200     Shape.apply(this, arguments);
201 }
202 Triangle.prototype = new Shape();
203 Triangle.prototype.name = 'Triangle';
204 //消除双重继承
205 function Shape(id){
206     this.id = id;
207 }
208 Shape.prototype.name = 'shape';
209 Shape.prototype.toString = function(){
210     return this.name;
211 }
212 function Triangle(){
213     Shape.apply(this, arguments);
214 }
215 function extend2(Child, Parent){
216     var p = Parent.prototype;
217     var c = Child.prototype;
218     for (var i in p){
219         c[i] = p[i];
220         c.uber = p;}
221 
222 }
223 extend2(Triangle, Shape);
224 Triangle.prototype.name = 'Triangle';
View Code
原文地址:https://www.cnblogs.com/niuxichuan/p/6476031.html