一、工厂模式
function createPerson(name, age, job) {
var person = {};
Object.defineProperties(person, {
_name: { writable: false, value: name},
_age:{writable:true, value: age},
job: {writable: true, value: job},
name:{
get: function(){return this._name}
},
age:{
get: function(){return this._age;},
set: function(newValue){this._age = newValue},
},
});
return person;
}
使用工厂模式可以有效的创建一个对象,但是却无法知道一个工厂模式对象实例的类型,例如在控制台中打印:
console.log(person instanceof createPerson);
会得到 false, 从而无法得知对象类型。
创造函数模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
}
}
如果此时实例化一个 person 的对象, 那么该实例会得到一个叫 constructor 的属性, 这个属性指向 Person。
person.constructor === Peron // true
// above is the same as below
person instanceof Person
同时构造函数模式可以作为函数使用, 而返回的值则会挂在 window 对象上
Person("Greg", 27, "Doctor");
alert(window.name);
这时候会出现一个问题:
this.sayName = new Function("console.log(this.name)");
上面这行代码和构造函数中的sayName 是逻辑等价, 也就是说 this.sayName 实际上创建的是一个匿名函数对象(原型),这种方式创建函数,则会导致不同的作用域链和标识符解析,但是实际上function的运行机制是一样的,也就是说,一旦使用该方法创建了两个或以上实例,相当于创建了两个或以上的一模一样功能的函数。
原型模式
function Person() {
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 28;
Person.prototype.job = "doctor";
Person.prototype.sayName = function(){
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
person1.name = "Elizabeth";
if(person1.name === person2.name); // false
原型模式虽然可以通过对象实例访问对象原型中的值,单不能通过对象实例重写原型中的值,对象实例中重写的值会直接覆盖掉原型的值,而不是重写它:
var person1 = new Person();
var person2 = new Person();
person1.name = "Elizabeth";
console.log(person1.name); //Elizabeth
delete person1.name;
console.log(person1.name); //Nicholas
更简单的原型模式
function Person(){
}
Person.prototype = {
name:"Nicholas",
age:27,
job:"doctor",
sayName:function() {
return this.name;
}
}
Object.defineProperties(person.prototype, "constructor", {
enumerable: false,
value: Person,
});
原型模式的共享本性
function Person(){
}
Person.prototype = {
name:"Nicholas",
age:27,
job:"doctor",
friends: ["Gerg","Court"],
sayName:function() {
return this.name;
}
}
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
console.log(person1.friends); // "Gerg","Court","Van"
console.log(person1.friends); //"Gerg","Court","Van"
组合使用构造函数模式和原型模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.friends = ["Shelby","Court"];
}
Person.prototype = {
sayName: function() {console.log(this.name);},
}
Object.definePropertites(Person, "constructor", {
enumerable: false,
value : Person,
})
动态原型模式
function Person(name, age, job){
this.name = name;
this.age = age;
this.friends = ["Shelby","Court"];
if( typeof this.sayName !== "function"){
Person.prototype.sayName = function() {
return this.name;
}
}
}
寄生构造函数模式
function Person(name, age, job){
var o = {};
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
return this.sayName;
}
return o;
}
稳妥构造函数模式
稳妥构造函数模式用以创建私有属性:
function DurableBook(name, year, edition){
var name = name;
var year = year;
var edition = edition;
this.getName = function(){
return name;
}
this.setName = function(newvalue){
name = newvalue;
}
}
var durable = new DurableBook("durable",2006,1);
console.log(durable.getName()); // durable
durable.setName("delicate");
console.log(durable.getName()); // delicate
console.log(durable.name); // undefined
网友评论