系统理解javascript面向对象编程
创建对象的四种方式:
(1) 工厂模式:
funciton createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name);
} return o; } var person1 = createPerson("pingzidong",23,"software engineer"); var person2 = createPerson("miaomiao",24,"teacher");
评价:
解决了创建多个相似对象的问题,但是没有解决对象识别的问题
(2) 构造函数模式:
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("pingzidong",27,"front-end engineer");
var person2 = new Person("pingjunyan",30,"teacher");
评价:
函数的三种用法:
1. 用作构造函数
2. 作为普通函数调用
3. 在另外一个对象的作用域中进行调用
不足:
同一个方法,每当创建一个实例,就需要一个实例一个新的Funtion()对象
(3) 原型模式:
function Person(){} Person.prototype.name = "pingzidong"; Person.prototype.age = 27; Person.prototype.job = "soft engineer"; Person.prototype.sayName = function(){ alert(this.name); } var person1 = new Person(); var person2 = new Person();
简单写法:
function Person(){} Person.prototype = { Constructor:Person, name:“pingzidong”, age:27, job:“soft engineer”, sayName:function(){ alert(this.name); } }
不足:
所有的实例共享属性和方法,对于引用类型的值(对象,数组,function),一个对象更改其值造成另外一个对象的该值的变化
(4) 组合使用构造函数模式和原型模式(普遍使用的模式)
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends =[“pingzidong”,“mm”]; } Person.prototype = { constructor:Person, sayName:function(){ alert(this.name); } }
继承的6种实现方式:
(1) 原型链
function SuperType(){ this.property = true; this.colors = [“red”,”blue”,”green”]; } SuperType.prototype.getSuperValue = function(){ return this.property; } function SubType(){ this.subproperty = false; } SubType.prototype = new SuperType(); // 创建子类型实例时,不能向超类型构造函数传递参数 SubType.prototype.getSubValue = function(){ return this.subproperty; } var instance1 = new SubType(); instance1.push(“black”); alert(instance1.colors) var instance2 = new SubType(); alert(instance2.colors); alert(instance.getSuperValue());
评价
(1) 所有的SubType实例共享colors属性,不同实例之间属性值互相影响
(2)创建子类型实例时,不能向超类型传递参数
(2) 借用构造函数
function SuperType(name){ this.name = name; this.colors = [“red“,”green”]; } SuperType.prototype.sayHello = function(){ alert(“hello world”); } function SubType(){ SuperType.call(this,”pingzidong2“) } var instance1 = new SubType(); intance1.colors.push(“black“); alert(instance1.name); alert(instance1.colors); var instance2 = new SubType(); alert(instance2.colors);
评价:
构造函数任务过重,无法复用
在超类型原型定义的方法对子类型不可见
(3) 组合继承
function SuperType(name){ this.name = name; this.colors = [“red”,”blue”,”black” ]; } SuperType.prototype.sayName = function(){ alert(this.name); } function Subtype(name,age){ SuperType.call(this,name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.constructor = SuperType; SubType.prototype.sayAge = function(){ alert(this.age); } var subtype = new SubType(“pppp”,23);
评价:
实现不同实例拥有自己的属性,包括引用属性,同时共享相同的方法
缺点:
2次调用超类型构造函数(父类),一次是在定义子类原型时,一次是在实例化子类时,可以参考寄生组合式继承
(4) 原型式继承
var person = { name:”fdsfsd”, friends:[“rd”,”re”,”fds”] } function object(o){ function F(){ } F.prototype = o; return new F(); } var another people = object(person); anotherpeople.name = “FDS”; anothpeople.friends.push(“dfs”); var yetanotherpeople = object(person); yetanotherpeople.friends.push(“fuss”); alert(person.friends);
评价:
没有构造函数使用原型继承(前提是已有对象)也可以搞定继承
需要注意的是:包含引用类型值的属性始终不用实例会共享,这点和原型链类似
(5) 寄生式继承
function createAnother(original){ var clone = object(original); clone.sayHi = function(){ alert(“hi“); } return clone; }
(6) 寄生组合式继承
function initPrototype(SubType,SuperType){ var prototype = object(Supertype.prototype); prototype.constructor = SubType; SubType.prototype = prototype; } function object(o){ function F(){} F.prototype = o; return new F(); }
评价:
可替换组合式继承中: SubType.prototype = new SuperType();
替换为: initPrototype(SubType,SuperType)