這篇文章主要介紹了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 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()
將資訊直接加入到原型物件上。使用原型的好處是可以讓所有的實例物件共享它所包含的屬性和方法,不必在建構函式中定義物件實例資訊。
<pre class="brush:js;">function Person() {
}
Person.prototype = {
name: ‘jiang&#39;,
job: ‘student&#39;,
sayName: function() {
console.log(this.name)
}
}
var person1 = new Person()</pre>
將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) // true
friends存在與原型中,實例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中文網其他相關文章!