javascript
JavaScript中创建对象的方法
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"); console.log(person1.name); //Nicholas var person2 = createPerson("Sofia",27,"Docter"); person2.sayName(); //Sofia?
2.構造函數模式
?可通過創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。構造函數始終都要應該以一個大寫字母開頭;要創建一個構造函數的新實例,必須使用new操作符。
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",25,"Chemical Engineer"); var person2 = new Person("Sofia",28,"Executive Manager"); console.log(person1 instanceof Object); //true console.log(person1 instanceof Person); //true console.log(person1.sayName==person2.sayName); //false使用構造函數模式可以確定對象的類型,但是上面像這樣將對象方法寫入構造函數內部會使得每個方法都要在每個實例上重新創建一遍。以這種方式創建的函數,會導致不同的作用域鏈和標識符來解析,因此不同實例上的同名函數是不相等的。
然而這樣是完全沒有必要的,創建任務相同的不同的Function實例。可將函數定義在構造函數外部,來解決這個問題。
但是如果對象需要定義很多方法,就需要定義很多全局函數,那么這個自定義的引用類型就毫無封裝性可言了。
?
3. 原型模式
?每個函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象,也就是原型對象,這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。這樣可以通過將屬性和方法直接添加到原型對象中來讓所有的對象實例來共享。
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Chemical Engieer"; Person.prototype.sayName = function(){alert(this.name);}; var person1 = new Person(); person1.sayName(); //Nicholas var person2 = new Person(); console.log(person2.age); //29 console.log(Person.prototype.isPrototypeOf(person1)); // true console.log(Object.getPrototypeOf(person1)==Person.prototype); //true person1.name = "Lisa"; console.log(person1.name); Lisa console.log(person1.hasOwnProperty("name")); //true在默認情況下,所有原型對象都會自動獲取一個constructor(構造函數)屬性,這個屬性是一個指向prototype屬性 所在函數的指針。創建了自定義的構造函數之后,其原型對象默認只會取得constructor屬性。當調用構造函數創建一個新實例后,該實例的內部包含一個指針(內部屬性),指向構造函數的原型對象,在ES5中叫[[Prototype]]。雖然在腳本中沒有標準的方式訪問[[Prototype]],但FireFox、Safari和Chrome在每個對象上都支持一個屬性_proto_。
但是當重寫整個原型對象時,即將Person.prototype設置為一個新對象時(如下),constructor屬性也變成了新對象的constructor屬性(指向Object構造函數),不再指向Person函數。
Person.prototype={name:"Nicholas",age: 29,job: "Software Engineer",sayName: function(){alert(this.name); } }如果constructor屬性很重要,可以在新原型對象上加上constructor:Person, 但是這樣constructor屬性的[[Enumerable]]特性被設置為true。默認情況下是不可枚舉的,false。
可以通過isPrototypeOf()方法確定某對象實例是否屬于某對象原型。如果實例的[[Prototype]]指向調用isPrototypeOf()方法的對象,那么這個方法返回true。
ES5中,增添了一個新方法,Object.getPrototypeOf(),這個方法返回[[Prototype]]的值。
使用hasOwnProperty()方法可以檢測一個屬性是存在于實例中還是存在于原型中。這個方法只有在給定屬性存在于對象實例中時,才會返回true。
?
4.構造函數模式和原型模式組合使用
?這種構造函數和原型混合的模式,目前子啊ECMAScript中使用最廣泛的一種創建自定義類型的方法。每個實例都會有自己的一份實例屬性的副本,同時也共享著方法的引用,極大程度低節省了內存。
function Person(name,age,job){this.name = name;this.age = age;this.job = job;this.friends = ["Shelby","Court"]; }Person.prototype={
construtor: Person,
sayName: function{
alert(this.name);
}
}
var person1=new Person("Nicholas",29,"Software Engineer");
var person2=new Person("Greg",27,"Chemical Engineer");
person1.friends.push("Sofia");
console.log(person1.friends); //["Shelby","Court","Sofia"]
console.log(person2.friends); //["Shelby","Court"]
?
?5.動態原型模式
同時使用構造函數與原型,僅在必要的情況下初始化原型。
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); } }?
6.穩妥構造函數模式
穩妥對象,指的是沒有公共屬性,而且方法也不引用this的對象。穩妥對象最適合在一些安全的環境(環境中會禁止使用this和new)中,或者在防止數據被其他應用程序改動時使用。
function createPerson(name,age,job){var o = new Object();//定義私有變量和函數//添加方法o.sayName = function() {alert(name); };//返回對象return o; }var friend=Person("Sofia",25,"Chemical Engineer"); friend.sayName(); //"Sofia"在上述的例子中,除了調用sayName()方法,沒有別的方式可以訪問到傳入到構造函數中的原始數據成員。
轉載于:https://www.cnblogs.com/SofiaTJU/p/9068092.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的JavaScript中创建对象的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P1027 Car的旅行路线
- 下一篇: 利用DOM进行照片的切换