javascript
JS创建对象学习笔记
一、創建對象
1.1 工廠模式
工廠模式抽象了創建具體對象的過程,用函數來封裝以特定接口創建對象的細節。代碼如下:
function createPerson(name, age, job) {var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function() {console.log(this.name);};return o; }var person1 = createPerson('sy', 25, 'Software Engineer') var person2 = createPerson('sansa', 25, 'Doctor')工廠模式的優點:解決創建多個相似對象的問題
缺點:無法解決對象識別的問題,即怎樣知道一個對象的類型
1.2 構造函數模式
構造函數可以創建特定類型的對象,如果是Object和Array這樣的原生構造函數,在運行時會出現在執行環境中,此外,也可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。
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('sy', 25, 'Software Engineer') var person2 = new Person('sansa', 25, 'Doctor')與構造函數不同之處:
沒有顯式地創建對象;直接將屬性和方法賦給了this對象;沒有return語句。
創建Person的新實例,必須使用new操作符。會經過以下步驟:
(1)創建一個新對象;
(2)將構造函數的作用域賦給新對象(因此this就指向了這個新對象);
(3)執行構造函數中的代碼(為這個新對象添加屬性);
(4)返回新對象。
person1和person2都有一個constructor(構造函數)屬性,該屬性指向Person。
person1.constructor == Person; // true構造函數的優點:可以清楚的知道一個對象的類型
缺點:構造函數中存在方法的話,每個Person實例都包含一個不同的Function實例。ECMAScript中的函數是對象,因此每定義一個函數,就是實例化了一個對象。如果將方法移到全局作用域的話,會導致這個函數只能被某個對象調用,這讓全局作用域名不副實。而且如果對象需要定義很多方法,那就要定義很多全局函數,這樣對自定義的引用類型沒有了封裝性。
1.3 原型模式(*)
使用原型對象的好處是:可以讓所有對象實例共享它所包含的屬性和方法。創建的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,prototype就是通過調用構造函數而創建的那個對象實例的原型對象。
function Person() { }Person.prototype.name = 'sy'; Person.prototype.age = 25; Person.prototype.job = 'Software Engineer'; Person.prototype.sayName = function() {console.log(this.name) };var person1 = new Person() person1.sayName() // 'sy'var person2 = new Person() person2.sayName() // 'sy'person1.sayName === person2.sayName // true__proto__存在于實例與構造函數的原型對象之間。
Person.prototype.isPrototypeOf(person1) // true
Object.getPrototypeOf(person1) == Person.prototype // true
注:使用for-in循環時,返回的是通過對象訪問的、可枚舉的屬性,包括實例中的屬性,也包括存在于原型中的屬性。要取得對象上所有可枚舉的實例屬性,使用ES5的Object.keys()方法,這個方法接收一個對象作為參數,返回一個包含所有可枚舉屬性的字符串數組。
如果要得到所有實例屬性,無論是否可枚舉,可以使用Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name"] 顯示了不可枚舉的constructor屬性
簡單的原型語法:
function Person(){ }Person.prototype = {name: 'sy',age: '25',job: 'Software Engineer',sayName: function() {console.log(name)} }constructor屬性不再指向Person了。每創建一個函數,就會同時創建它的prototype對象,這個對象也會自動獲得constructor屬性,而這個語法,本質上完全重寫了默認的prototype對象,因此constructor屬性也就變成了新對象的constructor屬性(指向Object構造函數),不再指向Person函數。通過constructor無法確定對象的類型了。可以強制將constructor: Person,但是會導致它的[[Enumerable]]特性設置為true。實例中的指針僅指向原型,而不指向構造函數。
原型模式的優點:可以共享屬性和方法
缺點:對于包含引用類型的屬性,會導致所有的對象都發生變化
1.4 組合使用構造函數模式和原型模式
構造函數模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。最大限度地節省了內存,而且這種模式支持向構造函數傳遞參數。
function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.friends = ['111', '222'] }Person.prototype = {constructor: Person,sayName: function() {console.log(this.name)} }var person1 = new Person('sy', 25, 'Software Engineer') var person2 = new Person('sansa', 25, 'Doctor')person1.friends.push('333')console.log(person1.friends === person2.friends) // false
1.5 動態原型模式
為了將構造函數和原型封裝,動態原型模式把所有信息都封裝在了構造函數中。可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
function Person(name, age, job){// 屬性this.name = name;this.age = age;this.job = job;// 方法if(typeof this.sayName != 'function'){Person.prototype.sayName = function() {console.log(this.name)}}}var friend = new Person('sy', 25, 'Software Engineer') friend.sayName(); // sy
使用動態原型模式時,不能使用對象字面量重寫原型。如果在已經創建了實例的情況下重寫原型,那么就會切斷現有實例與新原型之間的聯系。
1.6 寄生構造函數模式
思想:創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然后再返回新創建的對象。
function Person(name, age, job){var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function(){console.log(this.name);};return o; } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"1.7 穩妥構造函數模式
穩妥對象:指的是沒有公共屬性,而且其方法也不引用this的對象。
function Person(name, age, job){// 創建要返回的對象var o = new Object();// 可以在這里定義私有變量和函數// 添加方法o.sayName = function() {console.log(name)}// 返回對象return o; } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"?
轉載于:https://www.cnblogs.com/songya/p/11488887.html
總結
以上是生活随笔為你收集整理的JS创建对象学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.1计算机系统简介
- 下一篇: Cookie与Web Storage的区