// 这种继承借助原型并基于已有的对象创建对象,同时还不必因此创建自定义类型; function obj(o){ // 传递一个字面量函数; function F(){}; // 创建一个构造函数; F.prototype = o; // 把字面量函数赋值给构造函数的原型; return new F(); // 返回实例化的构造函数; } var box = { // 字面量对象; name:'Lee', arr:['brother','sisiter'] }; var box1 = obj(box); console.log(box1.name); // =>Lee; box1.name = 'Jack'; console.log(box1.name); // =>Jack; console.log(box1.arr); // =>brother,sister; box1.arr.push('father'); // console.log(box1.arr); // =>brother,sister,father; var box2 = obj(box); console.log(box2.name); // =>Lee; console.log(box2.arr); // =>brother,sister,father;引用类型共享了;
6.寄生式继承?
// 把原型式+工厂模式结合而来,目的是为了封装创建对象的过程; // 创建一个仅用于封装继承过程的函数, function create(o){ // 封装创建过程; var f = obj(o); f.run = function(){ return this.arr; // 同样会共享引用; }; return f; }
7.寄生组合式继承?
// 之前说过,组合式继承是JS最常用的继承模式; // 但是,组合式继承也有问题: // 超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部; function Box(name){ this.name = name; this.arr = ['brother','sister']; } Box.prototype.run = function(){ return this.name; } function Desk(name,age){ Box.call(this,name); // 第二次调用Box; this.age = age; } Desk.prototype = new Box(); // 第一次调用Box; // 寄生组合式继承: // 通过借用构造函数来继承属性, // 通过原型链的混成形式来继承方法; // 解决了两次调用的问题; function obj(o){ function F(){}; F.prototype = o; return new F(); } function create(box,desk){ var f = obj(box.prototype); f.constructor = desk; desk.prototype = f; } function Box(name){ this.name = name; this.arr = ['brother','sister']; } Box.prototype.run = function(){ return this.name; } function Desk(name,age){ Box.call(this,name); this.age = age; } inheritPrototype(Box,Desk); // 通过这里实现继承; var desk = new Desk('Lee',100); desk.arr.push('father'); console.log(desk.arr); console.log(desk.run()); var desk2 = new Desk('Jack',200); console.log(desk2.arr); // 两次引用问题解决;
四 小结
1.创建对象
对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体;
在没有类的情况下,可以采用下列模式创建对象;
(1).工厂模式:使用简单的函数创建对象,为对象添加属性和方法,然后返回对象;
这个模式后来被构造函数模式所取代;
(2).构造函数模式:可以自定义引用类型,可以像创建内置对象实例一眼使用new操作符;
缺点:它的每个成员都无法得到复用,包括函数;由于函数可以不局限于任何对象,因此没有理由不在多个对象间共享函数;
(3).原型模式:使用函数的prototype属性来指定那些应该共享的属性和方法;
组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,使用原型定义共享的属性和方法;
2.原型链
原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的;
子类型可以访问到超类型的所有属性和方法;
原型链的问题是对象实例共享所有继承的属性和方法,因此不适宜单独使用;
解决方案:借用构造函数,即在子类型构造函数的内部调用超类型构造函数;
这样就可以做到每个实例都具有自己的属性,同时还能保证只使用构造函数来定义类型;
使用最多的继承模式是组合继承;它使用原型链继承共享的属性和方法,而通过借用构造函数继承实例属性;
3.继承模式
(1).原型式继承:可以在不必预先定义构造函数的情况下实现继承;其本质是执行对给定对象的浅复制;
而复制得到的副本开可以得到进一步改造;
(2).寄生式继承:基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象;
为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用;
(3).寄生组合式继承:集寄生式继承和组合式继承的有点于一身,是实现基于类型继承的最有效方式;
您可能感兴趣的文章: