工厂模式
function 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("Nicholas", 29,"Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
构造函数创建对象
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("Nicholas", 29,"Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此this 就指向了z这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
每个方法都要在每个实例上重新创建一遍。
原型模式创建对象
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype 属性所在函数的指针
isPrototypeOf();
alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true
Object.getPrototypeOf()
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"
存在引用类型缺陷
/*
* 存在的问题
*/
function Person(){
}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");//只对P1进行了push;
/*但是下面P1、P2都发生了改变
*说明直接修改了friends数组(**引用类型**)
*/
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true
构造函数模式和原型模式
这种构造函数与原型混成的模式,是目前在ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。
/************************
* 构造函数+原型模式 *
* 构造函数来定义引用类型 *
* 最常用 *
************************
*/
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"];//这里
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name);
}
}
动态原型模式
/*
*
* 动态原型方法
*
*/
function Person(name, age, job) {
//属性
this.name = name;
this.age = age;
this.job = job;
//方法
if(typeof this.sayName != "function") {
Person.prototype.sayName = function() {
alert(this.name);
};
}
}
var friend = new Person("Nicholas", 29, "SoftwareEngineer");
friend.sayName();
寄生构造函数模式
/*
*
* 寄生构造函数模式
*
* 不能依赖instanceof 操作符来确定对象类型
*
* */
function Person(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 friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
寄生构造函数模式和工厂模式没有本质区别,通过new 操作符的就叫寄生构造函数模式,直接调用的就叫工厂模式
寄生构造函数专门用来为js原生的构造函数定义新的方法。。数组,字符串。
function SpecialArray() {
//创建数组
var values = new Array();
//添加值
values.push.apply(values, arguments);
//添加方法
values.toPipedString = function() {
return this.join("|");
};
//返回数组
return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green"
稳妥构造函数
/*
*
* 稳妥构造函数模式
*
* 没有公共属性,而且其方法也不引用this 的对象
*
* 数遵循与寄生构造函数类似的模式
*
* 新创建对象的实例方法不引用this
*
* 不使用new 操作符调用构造函数
*
* 与寄生构造函数模式类似,使用稳妥构造函数模式创建的对象
* 与构造函数之间也没有什么关系,
* 因此instanceof 操作符对这种对象也没有意义。
*
**/
function Person(name, age, job) {
//创建要返回的对象
var o = new Object();
//可以在这里定义私有变量和函数
//添加方法
o.sayName = function() {
alert(name);
};
//返回对象
return o;
}
//除了使用sayName()方法之外,没有其他办法访问name 的值。
var friend = Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"