1、工厂模式
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("Tom", 33, "SE");
var person2 = createPerson("Ken", 22, "MA");
person1.sayName();
person2.sayName();
//工厂模式,每次都会返回包含三个属性一个方法的对象
//问题,没有解决对象识别问题,即怎样知道一个对象的类型
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("TomCat", 33, "SE");
var person2 = new Person("KenKKK", 22, "MA");
//person1.sayName();
//person2.sayName();
//构造函数模式,
//1、Person()代替了createPerson()
//2、没有显示的创建对象 3、直接将属性和方法赋给了this对象
//4、没有return 5、要创建Person实例,必须使用new
//这两个对象都有一个contstructor属性,该属性指向Person
alert(person1.constructor == Person);//true
alert(person2.constructor == Person);//true
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
//构造函数与其他函数唯一区别就是,调用它们的方式不同
//作为构造函数使用
var person = new Person("TomCat333", 33, "SE");
person.sayName();
//作为普通函数使用
Person("KenKKK333", 33, "SE");//添加到window
window.sayName();
//在另一个对象的作用域中调用
var o = new Object();
Person.call(o,"TTT",25,"Nurse");
o.sayName();
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
var person1 = new Person("TomCat", 33, "SE");
var person2 = new Person("KenKKK", 22, "MA");
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
alert(person1.constructor == Person);//true
alert(person2.constructor == Person);//true
alert(person1.sayName == person2.sayName); //true
//问题:在全局作用域定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实
//如果对象需要定义很多方法,那么就要定义很多全局函数,没有封装行可言了
3、原型模式
//函数都有一个prototype(原型)属性,这个属性是一个对象,它的作用是包含可以有特定类型的所有实例共享的属性和方法
//prototype就是通过调用构造函数而创建的那个对象的原型对象
//使用原型的好处是可以让所有对象实例共享它所包含的属性和方法,
//换句话,不必在构造函数中定义对象信息,而是可以将这些信息直接添加到原型对象中
function Person(){}
Person.prototype.name="Tom";
Person.prototype.age=29;
Person.prototype.job="Software Engineer";
Person.prototype.sayName=function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName();
var person2 = new Person();
person2.sayName();
alert(person1.sayName()==person2.sayName());//true
解释:在此我们将方法和属性直接添加到了Person的prototype属性中,构造函数成了空函数//与构造函数不同的是,新对象的属性和方法是有所有实例共享的,
换句话说,person1和person2访问的都是同一组属性和方法
更简单的原型方法
function Person(){}
Person.prototype = {
constructor:Person,
name:"Nicholas",
age:22,
job:"SoftWare Engine",
sayName:function(){
alert(this.name);
}
};
var person = new Person();
alert(person instanceof Object);//t
alert(person instanceof Person);//t
alert(person.constructor == Person);//t
alert(person.constructor == Object);//f
组合使用构造函数模式和原型模式(最常用)
构造函数用于定义实例的属性,原型模式用于定义方法和共享的属性
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);
}
}
var person1 = new Person("Tom",22,"Software Engine");
var person2 = new Person("Greg",33,"Doctor");
person1.friends.push("van");
console.log(person1.friends);//"Shelby,Court,van"
console.log(person2.friends);//"Shelby,Court"
console.log(person1.friends===person2.friends);//f
console.log(person1.sayName===person2.sayName);//t