JavaScript創建對象的方式有很多,通過Object構造函數或對象字面量的方式也可以創建單個對象,顯然這兩種方式會產生大量的重復代碼,并不適合量產。接下來介紹七種非常經典的創建對象的方式,他們也各有優缺點。
工廠模式
function createPerson(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() { console.log(this.name) } return o } var person1 = createPerson('Jiang', 'student') var person2 = createPerson('X', 'Doctor') 可以無數次調用這個工廠函數,每次都會返回一個包含兩個屬性和一個方法的對象
工廠模式雖然解決了創建多個相似對象的問題,但是沒有解決對象識別問題,即不能知道一個對象的類型
構造函數模式
function Person(name, job) { this.name = name this.job = job this.sayName = function() { console.log(this.name) } } var person1 = new Person('Jiang', 'student') var person2 = new Person('X', 'Doctor') 沒有顯示的創建對象,使用new來調用這個構造函數,使用new后會自動執行如下操作
創建一個新對象
這個新對象會被執行[[prototype]]鏈接
這個新對象會綁定到函數調用的this
返回這個對象
使用這個方式創建對象可以檢測對象類型
person1 instanceof Object // true person1 instanceof Person //true
但是使用構造函數創建對象,每個方法都要在每個實例上重新創建一次
原型模式
function Person() { } Person.prototype.name = 'Jiang' Person.prototype.job = 'student' Person.prototype.sayName = function() { console.log(this.name) } var person1 = new Person() 將信息直接添加到原型對象上。使用原型的好處是可以讓所有的實例對象共享它所包含的屬性和方法,不必在構造函數中定義對象實例信息。
原型是一個非常重要的概念,在一篇文章看懂proto和prototype的關系及區別中講的非常詳細
更簡單的寫法
function Person() { } Person.prototype = { name: 'jiang', job: 'student', sayName: function() { console.log(this.name) } } var person1 = new Person()將Person.prototype設置為等于一個以對象字面量形式創建的對象,但是會導致.constructor不在指向Person了。
使用這種方式,完全重寫了默認的Person.prototype對象,因此 .constructor也不會存在這里
Person.prototype.constructor === Person // false
如果需要這個屬性的話,可以手動添加
function Person() { } Person.prototype = { constructor:Person name: 'jiang', job: 'student', sayName: function() { console.log(this.name) } } 不過這種方式還是不夠好,應為constructor屬性默認是不可枚舉的,這樣直接設置,它將是可枚舉的。所以可以時候,Object.defineProperty方法
新聞熱點
疑難解答
圖片精選