這篇文章主要介紹了JavaScript創建物件的七種方式,工廠模式,建構函數模式,原型模式等分別在本文中做出了講解,具體操作步驟大家可查看下文的詳細講解,感興趣的小夥伴們可以參考一下。
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 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方法
Object.defineProperty(Person.prototype, ‘constructor', { enumerable: false, value: Person })
#缺點
使用原型,所有的屬性都會被共享,這是個很大的優點,同樣會帶來一些缺點原型中所有屬性實例是被很多實例共享的,這種共享對於函數非常合適。對於那些包含基本值的屬性也勉強可以,畢竟實例屬性可以屏蔽原型屬性。但是引用類型值,就會出現問題了function Person() { } Person.prototype = { name: ‘jiang', friends: [‘Shelby', ‘Court'] } 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) // truefriends存在與原型中,實例person1和person2指向同一個原型,person1修改了引用的數組,也會反應到實例person2中
組合使用建構函式模式和原型模式
這是使用最為廣泛、認同度最高的一種建立自訂類型的方法。它可以解決上面那些模式的缺點使用此模式可以讓每個實例都會有自己的一份實例屬性副本,但同時又共享著對方法的引用這樣的話,即使實例屬性修改參考類型的值,也不會影響其他實例的屬性值了function Person(name) { this.name = name this.friends = [‘Shelby', ‘Court'] } Person.prototype.sayName = function() { console.log(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”] console.log(person1.friends === person2.friends) //false
## 動態原型模式 動態原型模式將所有資訊都封裝在了建構函式中,初始化的時候,透過偵測某個應該存在的方法時候有效,來決定是否需要初始化原型
#function Person(name, job) { // 属性 this.name = name this.job = job
// 方法 if(typeof this.sayName !== ‘function') { Person.prototype.sayName = function() { console.log(this.name) } } } var person1 = new Person(‘Jiang', ‘Student') person1.sayName()
只有在sayName方法不存在的時候,才會將它加入原型。這段程式碼只會初次呼叫建構函數的時候才會執行。
此後原型已經完成初始化,不需要在做什麼修改了
這裡對原型所做的修改,能夠立即在所有實例中得到反映
其次,if語句檢查的可以是初始化之後應該存在的任何屬性或方法,所以不必用一大堆的if語句檢查每一個屬性和方法,只要檢查一個就行
寄生構造函數模式這種模式的基本想法就是建立一個函數,該函數的作用只是封裝建立物件的程式碼,然後再傳回新建的物件
function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() { console.log(this.name) } return o } var person1 = new Person(‘Jiang', ‘student') person1.sayName()
这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样
构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值
稳妥构造函数模式
首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。
稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用
稳妥构造函数模式和寄生模式类似,有两点不同:一是创建对象的实例方法不引用this,而是不使用new操作符调用构造函数
function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() { console.log(name) } return o } var person1 = Person(‘Jiang', ‘student') person1.sayName()
和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上是JavaScript創建物件的七種方式(總結,必讀)的詳細內容。更多資訊請關注PHP中文網其他相關文章!