一 创立有同样接口的多个对象
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=29Person.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}//继承SuperTypeSubType.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);}
基本上防止了后面几种类型的毛病,是利用类型继承的最佳模式