标签:工厂 直接 修改属性 方法 asc logs 特定 解决 get
面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可
以创建任意多个具有相同属性和方法的对象。
第一种:基于Object对象
1 var person = new Object(); 2 person.name = "Nicholas"; 3 person.age = 29; 4 person.job = "Software Engineer"; 5 person.sayName = function(){ 6 alert(this.name); 7 };
第二种:对象字面量方式(比较清楚的查找对象包含的属性及方法)
1 var person = { 2 name: "Nicholas",
age: 29, 4 job: "Software Engineer", 5 sayName: function() { 6 alert(this.name); 7 } 8 };
ECMA-262 第 5 版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征 。ECMAScript中有两种属性:数据属性和访问器属性。
1 var person = {}; 2 Object.defineProperty(person, "name", { 3 configurable: false, 4 value: "Nicholas" 5 }); 6 alert(person.name); //"Nicholas" 7 delete person.name; 8 alert(person.name); //"Nicholas"
把 configurable 设置为 false,表示不能从对象中删除属性。如果对这个属性调用 delete,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。而且,一旦把属性定义为不可配置的,就不能再把它变回可配置了。此时,再调用 Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误.
在调用 Object.defineProperty()方法时,如果不指定, configurable、 enumerable 和
writable
特性的默认值都是 false。
1 var book = { 2 _year: 2004, 3 edition: 1 4 }; 5 Object.defineProperty(book, "year", { 6 get: function() { 7 return this._year; 8 }, 9 set: function(newValue) { 10 if(newValue > 2004) { 11 this._year = newValue; 12 this.edition += newValue - 2004; 13 } 14 } 15 }); 16 book.year = 2005; 17 alert(book.edition); //2
以上代码创建了一个 book 对象,并给它定义两个默认的属性: _year 和 edition。 _year 前面的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性。而访问器属性 year 则包含一个getter 函数和一个 setter 函数。 getter 函数返回_year 的值, setter 函数通过计算来确定正确的版本。因此,把 year 属性修改为 2005 会导致_year 变成 2005,而 edition 变为 2。这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。
虽然 Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体。
工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程(本书后面还将讨论其他设计模式及其在 JavaScript 中的实现)。考虑到在 ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下面的例子所示。
1 function createPerson(name, age, job) { 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.job = job; 6 o.sayName = function() { 7 alert(this.name); 8 }; 9 return o; 10 } 11 var person1 = createPerson("Nicholas", 29, "Software Engineer"); 12 var person2 = createPerson("Greg", 27, "Doctor");
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.sayName = function() { 6 alert(this.name); 7 }; 8 } 9 var person1 = new Person("Nicholas", 29, "Software Engineer"); 10 var person2 = new Person("Greg", 27, "Doctor");
使用自定义的构造函数(与普通函数一样,只是用它来创建对象),定义对象类型(如:Person)的属性和方法。它与工厂方法区别在于:
此外,要创建Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象创建;实际创建经过以下4个过程:
未完待续,后期再补
标签:工厂 直接 修改属性 方法 asc logs 特定 解决 get
原文地址:http://www.cnblogs.com/crbluesky/p/7674254.html