zoukankan      html  css  js  c++  java
  • 读《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
  • 相关阅读:
    EYES组——软件体系结构上机规划
    淘宝软件架构分析分工
    淘宝网系统架构分析以及数据库架构简介
    关于编译器与解释器的区别
    Web前端之高斯模糊图片记
    解决JS浮点数(小数)计算加减乘除的BUG
    JS滚轮事件(mousewheel/DOMMouseScroll)了解
    阻止事件冒泡
    记一次编码相关问题
    细说Form(表单)
  • 原文地址:https://www.cnblogs.com/niuxichuan/p/6476031.html
Copyright © 2011-2022 走看看