###工厂模式
function ellyLiang(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.getName = function() {
alert(this.name);
};
return o;
}
var person1 = ellyLiang("useLess", 24, "FF");
var person2 = ellyLiang("elly", 23, "none");
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别问题(即怎么知道一个对象的类型)
###构造函数模式
function Ellyliang(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.getName = function() {
console.log(this.name);
};
}
var person1 = new Ellyliang("useLess", 24, "FF");
var person2 = new Ellyliang("elly", 23, "none");
构造函数始终以大写字母开头,非构造函数以一个小写字母开头。 要创建Person的新实例,必须使用new操作符。
####构造函数与其他函数的区别在于他的调用方式的不同。
任何函数,只要通过new操作符来调用,那它就可以作为构造函数;而任何函数,如果它不通过new操作符来调用,那它跟普通函数也不会有什么两样。
//当作构造函数来使用
var person = new Ellyliang("useLess", 24, "FF");
person.getName(); //"useLess"
//当作普通函数调用
Ellyliang("elly", 23, "none"); //添加到window
window.getName(); //"elly"
//在另一个对象作用域中调用
var o = new Object();
Ellyliang.call(o, "LCM", 22, "student");
o.getName(); //"LCM"
####构造函数的问题:每个方法都要在每个实例上面重新创建一遍
不同实例上的同名函数是不相等的。
解决方法:
function Ellyliang(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.getName = getName;
}
function getName() {
console.log(this.name);
}
如果对象需要定义很多方法,那么就要定义很多个全局函数,于是这个自定义的引用类型就丝毫没有封装性可言了
###原型模式
prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。
function Ellyliang(){}
Ellyliang.prototype.name = "useless";
Ellyliang.prototype.age = 24;
Ellyliang.prototype.job = "FF";
Ellyliang.prototype.getName = function() {
console.log(this.name);
};
var person1 = new Ellyliang();
person1.getName(); //"useless"
var person2 = new Ellyliang();
person2.getName(); //"useless"
console.log(person1.getName() == person2.getName()); //true
####原型模式的缺点
省略了构造函数传递初始化参数,结果所有的实例在默认情况下都取得相同的属性值
原型中所有属性是被很多实例共享的,这种共享对于函数非常合适;但是对于包含引用类型的属性来说,问题就比较突出了。
function Ellyliang() {}
Ellyliang.prototype = {
constructor: Ellyliang,
name: "useless",
age: 24,
job: "FF",
friend: ["11", "22"],
getName: function(){
console.log(this.name);
}
};
var person1 = new Ellyliang();
var person2 = new Ellyliang();
person1.friend.push("33");
console.log(person1.friend); //"11, 22, 33"
console.log(person2.friend); //"11, 22, 33"
console.log(person1.friend === person2.friend); //true
###组合使用构造函数模式和原型模式
function Ellyliang(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friend = ["11", "22"];
}
Ellyliang.prototype = {
constructor: Ellyliang,
getName: function(){
console.log(this.name);
}
};
var person1 = new Ellyliang("useless", 24, "FF");
var person2 = new Ellyliang("elly", 23, "none");
person1.friend.push("33");
console.log(person1.friend); //"11, 22, 33"
console.log(person2.friend); //"11, 22"
console.log(person1.friend === person2.friend); //false
console.log(person1.getName ==== person2.getName); //false
构造函数模式和原型模式是最广泛,认同度最高的一种创建自定义类型的方法,用来定义引用类型的一种默认模式。
###动态原型模式
function Ellyliang(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
if(typeof this.getName != "function") {
Ellyliang.prototype.getName = function() {
console.log(this.name);
};
}
}
###寄生构造函数模式
function Ellyliang(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.getName = function() {
console.log(this.name);
};
return o;
}
var friend = Ellyliang("useless", 24, "FF");
friend.getName(); //"useless"