一 创建有同样接口的多个对象

1.工厂模式

function createPerson(name,age){
 let o = new Object()
    o.age=age
    o.sayName=function(){
      console.log("this.name")
    }
}
let person1 = createPerson("li",29) 
let person2 = createPerson("zhang",30) 

缺点:没有解决对象的表示同意恩问题,不知道对象属于哪个类型

2.构造函数模式

function Person(name,age){
    this.age=age
    this.sayName=function(){
      console.log("this.name")
    }
    //this.sayName = new Function(console.log("this.name"))
}
let person1 = new Person("li",29) 
let person2 = new Person("zhang",30) 

//将方法转移到外部
function Person(name,age){
    this.age=age
}
function sayName=function(){
      console.log("this.name")
}
let person1 = new Person("li",29) 
let person2 = new Person("zhang",30) 

缺点:实例化多个对象时,实际上重复创建了多个相同的方法(sayName()),可以将方法转移到外部,但这相当于定义了全局方法,不能将自定义类型引用到代码很好的聚集起来

3.原型模式

/*无论如何,只要创建一个函数,就会按照特定的规则为这个函数创建一个prototype属性(指向
原型对象)。默认情况下,所有的原型对象自动或得一个名为constructor的属性,指回与之关联的构造函数*/
function Person(){}
Person.prototype.name="li"
Person.prototype.age=29
Person.prototype.sayName=function(){
      console.log("this.name")
}
//上面的代码比较冗余 用对象字面量来重写
//用字面量来重写 会覆盖默认的contructor属性 造成此属性丢失,所以要手动加回来
Person.prototype={
    constructor:Person, 
    name:"li",
    age:29,
    sayName:function(){
          console.log("this.name")
    }
}

缺点 (1)弱化了向构造函数传递初始化参数的能力 (2)所有实例共享了相同的属性,如果属性时引用类型则会相互影响

二 对象之间如何继承

1.原型链继承

function SuperType(){
 this.property=true;
}
SuperType.prototype.getSuperValue=function(){
 return this.property;
}
function SubType(){
 this.subproperty=false
}
//继承SuperType
SubType.prototype= new SuperType();
//新方法
SubType.prototype.getSubValue= function(){
 return this.subproperty;
}
//覆盖原有的方法
SubType.prototype.getSuperValue = function(){
    return false;
}

let instance = new SubType();

缺点 和前面用原型模式构造 对象一样,原型种包含引用值的时候对象之间会相互影响,同时子类在实例化的时候不能给父类传递参数

2 盗用构造函数 与 组合继承

function SuperType(){
 this.colors=["red","blue","greed"]
}

function SubType(){
//继承SuperType
 SuperType.call(this)
}
let instance1= new SubType();
instance1.colors.push("black");
console.log(instance1.colors) // "red,blue,green,black"
let instance2= new SubType();
console.log(instance2.colors) // "red,blue,green"

//盗用构造函数的缺点是必须在构造函数中定义方法,而且 无法重用父类的方法
//组合继承

function SuperType(name){
 this.name=name
 this.colors=["red","blue","greed"]
}
SuperType.prototype.sayName=function(){
      console.log("this.name")
}
function SubType(name,age){
//继承SuperType
 SuperType.call(this); // 第二次调用 SuperType()
this.age=age
}
SubType.prototype= new SuperType(); // 第一次调用 SuperType()
SubType.prototype.sayAge=function(){
 console.log(this.age)
}
let instance1= new SubType("li",29);
instance1.colors.push("black");
console.log(instance1.colors) // "red,blue,green,black"
instance1.sayName() // "li"
let instance2= new SubType("zhang",30);
console.log(instance2.colors) // "red,blue,green"
instance2.sayName() //"zhang"

缺点 两次调用父类的构造函数,有效率问题

3.寄生组合继承

function inheritPrototype(subType,superType){
 let prototype= object(superType.protoType); //复制父类原型
  prototype.constructor=subType;
  subType.prototype=prototype
}
function SuperType(name){
 this.name=name
 this.colors=["red","blue","greed"]
}
SuperType.prototype.sayName=function(){
      console.log("this.name")
}
function SubType(name,age){
//继承SuperType
 SuperType.call(this); // 第二次调用 SuperType()
 this.age=age
}
interitPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
 console.log(this.age);
}

基本上避免了前面几种类型的缺点,是应用类型继承的最佳模式


lcf1122
5 声望0 粉丝

« 上一篇
Git 常用命令