关于javascript:JavaScript-高级程序设计学习笔记一-第8章-对象-类与面向对象编程

7次阅读

共计 3013 个字符,预计需要花费 8 分钟才能阅读完成。

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

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);
}

基本上防止了后面几种类型的毛病,是利用类型继承的最佳模式

正文完
 0