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