javascript 设计模式

来源:互联网 发布:matlab2016拟合数据 编辑:程序博客网 时间:2024/04/29 19:30

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('Nicholas', 29, "Software Engineer");var person2 = createPerson('haojie', 28, "Web Developer");person1.sayName(); // Nicholasperson2.sayName(); // haojie


2. 构造函数模式(不完美)

function Person(name, age, job){this.name = name;this.age = age;this.job = job;this.sayName = function(){console.log(this.name);}}var person1 = new Person('Nicholas', 29, 'Software Engineer');var person2 = new Person('haojie', 28, 'Web Developer');person1.sayName();person2.sayName();

其中第5行sayName Function实际等同于
this.sayName = new Function("alert(this.name)");  // 与声明函数在逻辑上是等价的
每个Person实例都包含一个不同的Function实例,下面的代码能证明这两个函数是不相等的
console.log(person1.sayName == person2.sayName); //false
然而,创建两个完全同样的任务的Function实例的确没有必要。


3. 原型模式(不完美)

function Person(){}Person.prototype = {constructor: Person,name: 'Nicholas',age: 29,job: 'Software Engineer',friends: ['Shelby', 'Court'],sayName: function(){console.log("sayName function say: " + this.name);}}var person1 = new Person();var person2 = new Person();person1.friends.push("Van");console.log(person1.friends); // "Shelby, Court, Van"console.log(person2.friends); // "Shelby, Court, Van"console.log(person1.friends == person2.friends);// true
在此,Person.prototype对象有一个名为friends的属性, 该属性包含一个字符串数组。然后创建了Person的两个实例。接着,修改了person1.friends引用的数组,想数组中添加了一个字符串。由于friends数组存在于Person.prototype而非person1中,所以刚刚提到的修改也会通过person2.friends(与person1.friends指向同一个数组)反映出来。

4. 组合使用构造函数模式和原型模式(Nicholas 推荐)

// 实例属性定义在【构造函数】中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("Nicholas", 29, "Software Engineer");var person2 = new Person("Greg", 29, "Doctor");person1.friends.push("Van");console.log(person1.friends); // Shelby, Court, Vanconsole.log(person2.friends); // Shelby, Courtconsole.log(person1.friends == person2.friends); // falseconsole.log(person1.sayName == person2.sayName); // true


5. 动态原型模式(Nicholas推荐)

function Person(name, age, job, friends){// 属性this.name = name;this.age = age;this.job = job;this.friends = friends;// 方法// 这里只有在sayName不存在的情况下,才会将它添加到原型中// 也就是new person1的时候会被call到,new person2的时候就不会走这里了if(typeof this.sayName != "function"){Person.prototype.sayName = function(){console.log(this.name);};}}var person1 = new Person("Nicholas", 29, "Software Engineer", ["Shelby", "Court"]);var person2 = new Person("haojie", 29, "Software Engineer", ["Shelby", "Court"]);person1.sayName(); //  Nicholasperson2.sayName(); // haojieperson1.friends.push('Van');console.log(person1.friends); // Shelby,Court,Vanconsole.log(person2.friends); // Shelby,Courtconsole.log(person1.friends == person2.friends); // falseconsole.log(person1.sayName == person2.sayName); // true

6. 寄生(parasitic)构造函数模式(不推荐)

不能使用person1 instanceof Person 操作符来确定对象类型


7. 稳妥(durable objects)构造函数模式(安全)

function Person(name, age, job, friends){// 创建要返回的对象var o = new Object();// 可以在这里定义私有变量和函数// 添加方法o.sayName = function(){console.log(name);};// 返回对象return o;}var person = Person('Nicholas', 29, 'Software Engineer');person.sayName(); // Nicholasconsole.log(person instanceof Person); // false

这样,变量person中保存的是一个稳妥对象,而除了调用sayName()方法外,没有别的方式可以访问其数据成员。稳妥构造函数提供的这种安全性,使得它非常适合在某些安全执行环境下使用。

与寄生构造函数模式类似,使用稳妥构造函数模式创建的对象与构造函数之间也没有关系(因为用的是new Object, 然后return的方法),因此instanceof操作符对这种对象也没有意义。

原创粉丝点击