工厂模式
解决:对象字面量大量重复代码的问题(创建多个相似变量时)
问题:存在对象识别问题

function ceateObj(name,age){
      
        var obj=new Object();
        obj.name=name;
        obj.age-age;
        obj.showAge=function(){
          alert(this.name)  
    }   
  return obj; }

var person=createObj('aaa','22');

 

构造函数模式
解决了工厂模式无法解决对象识别问题
问题:每个方法都要在实例上重新创建一次,即两个实例访问的方法不一样
function Person(name,age){ this.name=name; this.age=age; this.showAge=function(){ alert(this.name) } } var person=new Person('aaa','11');

  person instanceof Person;//true
  person instanceof Object;//true


与工厂模式的区别:没有显式创建对象;直接将属性和方法赋给了对象;没有return语句;创建实例要用new 语句
原型模式:
解决实例共享属性和方法问题
问题:所有实例属性都相同,引用相同
function Person(){ } Person.prototype.name='aaa'; Person.prototype.age='11' Person.prototype.showAge=function(){ alert(this.name) } var person1=new Person(); var person2=new Person(); person1.showAge();//11 person2.showAge();//11

 

组合使用构造函数和原型模式
构造函数用于定义实例
原型模式用于定义方法和共享属性

function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.showAge=function(){
    alert(this.age)
}


 

 

动态原型模式
优点:仅在需要的情况下定义原型方法
function Person(name,age){
    this.name=name;
    this.age=age;
    
    if(typeof this.showAge!='function'){//只有初次调用构造函数时执行,不需要每个属性判断,只判断一个即可
        Person.prototype.showAge=function(){
            alert(this.age)
        }
    }
}

 

 

寄生构造函数,本质和工厂方法一样,只是寄生方法重写return值覆盖了new构造函数的return this

function Person(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.showAge=function(){
        console.log(this.age);
    }
    
    return obj;
}

var per=new Person('aa',11);

per.showAge()

注意:返回的对象与构造函数或者与构造函数的原型属性之间没有关系,per instanceof Person为false

 

 

稳妥构造函数模式
稳妥对象就是没有公共属性,而且其方法也不引用this对象,不使用new操作符调用构造函数
function Person(name,age){
    var obj=new Object();
    obj.sayAge=function(){
        console.log(age);//这种模式创建的方法除了调用sayage以外没有其他方法可以访问age属性
    }
}

 

继承

 

原型链继承
function Super(){
    this.color=['red','yellow'];
    this.test='false';

}
Super.prototype.getColor=function(){
    return this.color;
}
function sub(){
    this.color=['fff'];
}
Sub.prototype=new Super();
//问题:通过这方式创建的属性如果子类中没有相同名称的属性如color,则会想原型属性一样共享如test
//问题二:在创建子类型的实例时,不能向超类的构造函数中传递参数,没有办法在不影响所有实例的情况下给超类的构造函数传递参数

 

 

 

借用构造函数继承
function Super(){
    this.color=['red','yellow'];

}
function sub(){
    Super.call(this);
}
//方法都只能在构造函数中定义,不能复用

 

组合继承

function Super(name,age){
    this.name=name;
    this.age=age;

}
Suoer.prototype.showAge=function(){
    console.log(this.name);
}
function Sub(name,age){
    Super.call(this,name,age);
}
Sub.prototype=new Super();
Sub.prototype.constructor=Sub;//修改指向
原型式继承
function Create(o){
    function F(){}
    F.prototype=o;
    return new F();
}

var data={
    name:'aa',
    age:11,
    color:['red']
}
var c1=Create(data);
var c2=Create(data);
c1.name='cc';
c1.color.push('yellow')
console.log(c2.name)//aa
console.log(c1.name)//cc
console.log(c2.color)//[red,yellow]浅复制
寄生式继承
function anotherCreate(o){
    var clone=Create(o);
    clone.say=function(){
        console.log(this.name)

    }
    return clone;
}
var clone=anotherCreate(data);
clone.say()
//类似于工厂模式

 

 

寄生组合式继承
组合式继承最大的问题是无论什么情况下都会调用两次超类,一次是创建子类原型时,一次是在子类的构造函数内部

function inherite(super,sub){
    var prototype=Create(super.prototype);
    prototype.constructor=sub;
    sub.prototype.prototype;
}

function Super(name){
    this.name=name;
}
Super.prototype.say=function(){
    console.log(this.name);
}
function Sub(naem){
    Super.call(this,name);
}
inherite(Super,Sub)