JavaScript高级程序设计(第3版)学习笔记10 再访(7)

function create(o){ var fn = function(){}; fn.prototype = o; return new fn(); } var square = { width:10, coordinate:[0,0] }; var cs = create(square); var cs2 = create(square); console.info(cs.coordinate);//[0,0] console.info(cs2.coordinate);//[0,0] cs.coordinate[1] = 1; console.info(cs.coordinate);//[0,1] console.info(cs2.coordinate);//[0,1],和原型链一样,会有共享问题

 

1、这种方式实际上就是前面说的模拟ES5中create函数来实现继承。

2、ES5及前面模拟的create还可以接受另外的属性描述参数。

3、和原型链与借用构造函数不同的是,这种方式需要先有一个对象,然后直接创建子对象。

前者是构造函数的继承,而后者是对象实例的继承。

4、和使用原型链继承一样,也会有引用类型实例属性的共享问题。

 
寄生式继承  

function create(o){ var fn = function(){}; fn.prototype = o; return new fn(); } var square = { width:10, coordinate:[0,0] }; function colorSquare(original){ var s = create(original); s.color = 'red'; return s; } var cs = colorSquare(square); console.info(cs.width);//10 console.info(cs.coordinate);//[0,0]

 

1、首先,这里的create函数不是必需的,任何返回新对象的函数都可以。

2、其次,这种模式也有引用类型实例属性共享的问题。

3、这种方式,可以看成将上面的对象继承包装成构造函数。

 
寄生组合式继承  

function create(o){ var fn = function(){}; fn.prototype = o; return new fn(); } function inherit(sub, sup){ var prototype = create(sup.prototype); prototype.constructor = sub; sub.prototype = prototype; } function Square(){//正方形 this.width = 10;//边长 this.coordinate = [0,0];//左上顶点的坐标 } Square.prototype.getArea = function(){//计算面积 return this.width * this.width; }; function ColorSquare(){//有颜色的正方形 Square.call(this); this.color = 'red'; } inherit(ColorSquare, Square); ColorSquare.prototype.getColor = function(){//获取颜色 return this.color; } var cs = new ColorSquare(); console.info(cs.width);//10 console.info(cs.getArea());//100 console.info(cs.color);//red console.info(cs.getColor());//red var cs2 = new ColorSquare(); console.info(cs2.coordinate);//[0,0] cs.coordinate[1] = 1; console.info(cs2.coordinate);//[0,0]

 

1、这种方式只调用了一次父类构造函数,从而避免了在子类型的原型对象上创建不必要的属性。

2、能够保证原型链不变,从而可以正常使用instanceof和isPrototypeOf()。

 

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wddsdz.html