中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

在javascript中創(chuàng)建對象的各種模式解析
來源:易賢網(wǎng) 閱讀:1028 次 日期:2016-06-27 16:46:18
溫馨提示:易賢網(wǎng)小編為您整理了“在javascript中創(chuàng)建對象的各種模式解析”,方便廣大網(wǎng)友查閱!

下面小編就為大家?guī)硪黄趈avascript中創(chuàng)建對象的各種模式解析。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考

最近在看《javascript高級程序設(shè)計》(第二版)

javascript中對象的創(chuàng)建

•工廠模式

•構(gòu)造函數(shù)模式

•原型模式

•結(jié)合構(gòu)造函數(shù)和原型模式

•原型動態(tài)模式

面向?qū)ο蟮恼Z言大都有一個類的概念,通過類可以創(chuàng)建多個具有相同方法和屬性的對象。雖然從技術(shù)上講,javascript是一門面向?qū)ο蟮恼Z言,但是javascript沒有類的概念,一切都是對象。任意一個對象都是某種引用類型的實例,都是通過已有的引用類型創(chuàng)建;引用類型可以是原生的,也可以是自定義的。原生的引用類型有:Object、Array、Data、RegExp、Function。 !引用類型就是一種數(shù)據(jù)結(jié)構(gòu),將數(shù)據(jù)和功能組織在一起,通常被稱為類。 缺乏類概念的javascript中,需要解決的問題就是如何高效的創(chuàng)建對象。

1.1.0.創(chuàng)建對象的一般方法

var person = {}; //對象字面量表示,等同于var person = new Objcect();

person.name = 'evansdiy';

person.age = '22';

person.friends = ['ajiao','tiantian','pangzi'];

person.logName = function() {

  console.log(this.name);

}

基于Object引用類型,創(chuàng)建了一個對象,該對象包含四個屬性,其中一個為方法。如果需要很多類似person的實例,那就會有許多重復的代碼。

1.1.1.工廠模式

通過一個可以包含了對象細節(jié)的函數(shù)來創(chuàng)建對象,然后返回這個對象。

function person(name,age,friends) {

  var o = {

    name: name,

    age: age,

    friends: friends,

    logName: function() {

      console.log(this.name);

    }

  };

  return o;

}

var person1 = person('Evansdiy','22',['ajiao','tiantian','pangzi']);

每次調(diào)用person函數(shù),都會通過該函數(shù)內(nèi)部的對象o創(chuàng)建新的對象,然后返回,除此之外,這個為了創(chuàng)建新對象而存在的內(nèi)部對象o沒有其他的用途。另外,無法判斷工廠模式創(chuàng)建的對象的類型。

1.1.2.構(gòu)造函數(shù)模式

function Person(name,age,job) {

  this.name = name;

  this.age = age;

  this.job = job;

  this.logName = function() {

    console.log(this.name);

  }

}

//通過new操作符創(chuàng)建Person的實例

var person1 = new Person('boy-a','22','worker');

var person2 = new Person('girl-b','23','teacher');

person1.logName(); //boy-a

person2.logName(); //girl-a

對比工廠模式,可以發(fā)現(xiàn),這里并不需要創(chuàng)建中間對象,沒有return。另外,可以將構(gòu)造函數(shù)的實例標識為一種特定的類型,這就解決了對象識別的問題(通過檢查實例的constructor屬性,或利用instanceof操作符檢查該實例是否通過某個構(gòu)造函數(shù)創(chuàng)建)。

console.log(person1.constructor == Person);//constructor位于構(gòu)造函數(shù)原型中,并指向構(gòu)造函數(shù),結(jié)果為true

console.log(person1 instanceof Person);//通過instanceof操作符,判斷person1是否為構(gòu)造函數(shù)Person的實例但構(gòu)造函數(shù)模式也有自己的問題,實際上,logName方法在每個實例上都會被重新創(chuàng)建一次,需要注意的是,通過實例化創(chuàng)建的方法且并不相等,以下代碼將會得到false:

console.log(person1.logName == person2.logName);//false我們可以將方法移到構(gòu)造器外部(變?yōu)槿趾瘮?shù))來解決這個問題:

function logName() {

  console.log(this.name);

}

function logAge() {

  console.log(this.age);

}

但是,在全局下創(chuàng)建的全局函數(shù)實際上只能被經(jīng)由Person創(chuàng)建的實例調(diào)用,這就有點名不副實了;如果方法很多,還需要逐一定義,缺少封裝性。

1.1.3.原型模式

javascript中的每一個函數(shù)都包含一個指向prototype屬性的指針(大部分瀏覽器可以通過內(nèi)部屬性__proto__訪問),prototype屬性是一個對象,其中包含了由某種引用類型創(chuàng)建的所有實例共享的屬性和方法。

function Person() {}

Person.name = 'evansdiy';

Person.prototype.friends = ['ajiao','jianjian','pangzi'];

Person.prototype.logName = function() {

  console.log(this.name);

}

var person1 = new Person();

person1.logName();//'evansdiy'

以上代碼做了這幾件事情:

1.定義了一個構(gòu)造函數(shù)Person,Person函數(shù)自動獲得一個prototype屬性,該屬性默認只包含一個指向Person的constructor屬性;

2.通過Person.prototype添加三個屬性,其中一個作為方法;

3.創(chuàng)建一個Person的實例,隨后在實例上調(diào)用了logName()方法。 !

這里需要注意的是logName()方法的調(diào)用過程:

1.在person1實例上查找logName()方法,發(fā)現(xiàn)沒有這個方法,于是追溯到person1的原型

2.在person1的原型上查找logame()方法,有這個方法,于是調(diào)用該方法 基于這樣一個查找過程,我們可以通過在實例上定義原型中的同名屬性,來阻止該實例訪問原型上的同名屬性,需要注意的是,這樣做并不會刪除原型上的同名屬性,僅僅是阻止實例訪問。

var person2 = new Person();

person2.name = 'laocai';如果我們不再需要實例上的屬性時,可以通過delete操作符刪除。

delete person2.name;利用for-in循環(huán)枚舉出實例可以訪問到的所有屬性(不論該屬性存在于實例或是原型中):

for(i in person1) {

  console.log(i);

}

同時,也可以利用hasOwnProperty()方法判斷某個屬性到底存在于實例上,還是存在于原型中,只有當屬性存在于實例中,才會返回true:

console.log(person1.hasOwnProperty('name'));//true!hasOwnProperty來自O(shè)bject的原型,是javascript中唯一一個在處理屬性時不查找原型鏈的方法。[via javascript秘密花園] 另外,也可以通過同時使用in操作符和hasOwnProperty()方法來判斷某個屬性存在于實例中還是存在于原型中:

console.log(('friends' in person1) && !person1.hasOwnProperty('friends'));先判斷person1是否可以訪問到friends屬性,如果可以,再判斷這個屬性是否存在于實例當中(注意前面的!),如果不存在于實例中,就說明這個屬性存在于原型中。 前面提到,原型也是對象,所以我們可以用對象字面量表示法書寫原型,之前為原型添加代碼的寫法可以修改為:

Person.prototype = {

  name: 'evansdiy',

  friends: ['ajiao','jianjian','pangzi'],

  logName: function() {

    console.log(this.name);

  }

}

由于對象字面量語法重寫了整個prototype原型,原先創(chuàng)建構(gòu)造函數(shù)時默認取得的constructor屬性會指向Object構(gòu)造函數(shù):

//對象字面量重寫原型之后

console.log(person1.constructor);//Object不過,instanceof操作符仍會返回希望的結(jié)果:

//對象字面量重寫原型之后

console.log(person1 instanceof Person);//true當然,可以在原型中手動設(shè)置constructor的值來解決這個問題。

Person.prototype = {

  constructor: Person,

  ......

}

如果在創(chuàng)建對象實例之后修改原型對象,那么對原型的修改會立即在所有對象實例中反映出來:

function Person() {};

var person1 = new Person();

Person.prototype.name = 'evansdiy';

console.log(person1.name);//'evansdiy'

實例和原型之間的連接僅僅是一個指針,而不是一個原型的拷貝,在原型實際上是一次搜索過程,對原型對象的所做的任何修改都會在所有對象實例中反映出來,就算在創(chuàng)建實例之后修改原型,也是如此。 如果在創(chuàng)建對象實例之后重寫原型對象,情況又會如何?

function Person() {};

var person1 = new Person1();//創(chuàng)建的實例引用的是最初的原型

//重寫了原型

Person.prototype = {

  friends: ['ajiao','jianjian','pangzi']

}

var person2 = new Person();//這個實例引用新的原型

console.log(person2.friends);

console.log(person1.friends);

以上代碼在執(zhí)行到最后一行時會出現(xiàn)未定義錯誤,如果我們用for-in循環(huán)枚舉person1中的可訪問屬性時,會發(fā)現(xiàn),里頭空無一物,但是person2卻可以訪問到原型上的friends屬性。 !重寫原型切斷了現(xiàn)有原型與之前創(chuàng)建的所有對象實例的聯(lián)系,之前創(chuàng)建的對象實例的原型還在,只不過是舊的。

//創(chuàng)建person1時,原型對象還未被重寫,因此,原型對象中的constructor還是默認的Person()

console.log(person1.constructor);//Person()

//但是person2的constructor指向Object()

console.log(person2.constructor);//Object()

需要注意的是,原型模式忽略了為構(gòu)造函數(shù)傳遞參數(shù)的過程,所有的實例都取得相同的屬性值。同時,原型模式還存在著一個很大的問題,就是原型對象中的引用類型值會被所有實例共享,對引用類型值的修改,也會反映到所有對象實例當中。

function Person() {};

Person.prototype = {

  friends: ['ajiao','tiantian','pangzi']

}

var person1 = new Person();

var person2 = new Person();

person1.friends.push('laocai');

console.log(person2.friends);//['ajiao','tiantian','pangzi','laocai']

修改person1的引用類型值friends,意味著person2中的friends也會發(fā)生變化,實際上,原型中保存的friends實際上只是一個指向堆中friends值的指針(這個指針的長度是固定的,保存在棧中),實例通過原型訪問引用類型值時,也是按指針訪問,而不是訪問各自實例上的副本(這樣的副本并不存在)。

1.1.4.結(jié)合構(gòu)造函數(shù)和原型模式創(chuàng)建對象

結(jié)合構(gòu)造函數(shù)和原型模式的優(yōu)點,彌補各自的不足,利用構(gòu)造函數(shù)傳遞初始化參數(shù),在其中定義實例屬性,利用原型定義公用方法和公共屬性,該模式應(yīng)用最為廣泛。

function Person(name,age) {

  this.name = name;

  this.age = age;

  this.friends = ['ajiao','jianjian','pangzi'];

}

Person.prototype = {

  constructor: Person,

  logName: function() {

    console.log(this.name);

  }

}

var person1 = new Person('evansdiy','22');

var person2 = new Person('amy','21');

person1.logName();//'evansdiy'

person1.friends.push('haixao');

console.log(person2.friends.length);//3

1.1.5.原型動態(tài)模式

原型動態(tài)模式將需要的所有信息都封裝到構(gòu)造函數(shù)中,通過if語句判斷原型中的某個屬性是否存在,若不存在(在第一次調(diào)用這個構(gòu)造函數(shù)的時候),執(zhí)行if語句內(nèi)部的原型初始化代碼。

function Person(name,age) {

  this.name = name;

  this.age = age;

  if(typeof this.logName != 'function') {

    Person.prototype.logName = function() {

      console.log(this.name);

    };

    Person.prototype.logAge = function() {

      console.log(this.age);

    };

  };

}

var person1 = new Person('evansdiy','22');//初次調(diào)用構(gòu)造函數(shù),此時修改了原型

var person2 = new Person('amy','21');//此時logName()方法已經(jīng)存在,不會再修改原型

需要注意的是,該模式不能使用對象字面量語法書寫原型對象(這樣會重寫原型對象)。若重寫原型,那么通過構(gòu)造函數(shù)創(chuàng)建的第一實例可以訪問的原型對象不會包含if語句中的原型對象屬性。

function Person(name,age) {

  this.name = name;

  this.age = age;

  if(typeof this.logName != 'function') {

    Person.prototype = {

      logName: function() {

        console.log(this.name);

      },

      logAge: function() {

        console.log(this.Age);

      }

    }

  };

}

var person1 = new Person('evansdiy','22');

var person2 = new Person('amy','21');

person2.logName();//'amy'

person1.logName();//logName()方法不存在

需要說明的是,各模式都有自己的應(yīng)用場景,無所謂優(yōu)劣。

以上這篇在javascript中創(chuàng)建對象的各種模式解析就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機網(wǎng)站地址:在javascript中創(chuàng)建對象的各種模式解析

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
欧美四级伦理在线| 一区在线电影| 午夜在线不卡| 国产精品户外野外| 亚洲愉拍自拍另类高清精品| 欧美日韩中文字幕精品| 亚洲淫片在线视频| 欧美日韩在线另类| 99精品视频免费观看视频| 欧美日韩国产一区二区| 91久久综合| 欧美系列精品| 久久久久久有精品国产| 国产精品一区二区久久久久| 香蕉久久国产| 亚洲日本在线视频观看| 国产日韩在线视频| 欧美激情欧美激情在线五月| 亚洲精品影视| 亚洲高清二区| 国产日韩在线看片| 欧美激情一区二区三区在线视频| 亚洲人体1000| 精品99一区二区| 国产精品系列在线播放| 欧美成人有码| 久久久久久欧美| 欧美一区二区| 欧美一级播放| 亚洲欧美在线x视频| 日韩一区二区福利| 亚洲精品午夜精品| 亚洲精品乱码久久久久久| 在线观看91精品国产入口| 国产在线视频欧美一区二区三区| 国产精品二区在线| 国产精品视频xxx| 国产精品区一区二区三区| 欧美日韩精品系列| 国产欧美一区二区三区在线看蜜臀| 欧美激情一区二区久久久| 欧美精品三区| 亚洲免费成人av电影| 亚洲国产日韩欧美综合久久| 亚洲大片在线| 日韩视频永久免费观看| 亚洲一区二区三区在线看| 亚洲男同1069视频| 久久免费少妇高潮久久精品99| 欧美在线关看| 欧美日韩在线一区二区三区| 国产精品主播| 91久久久在线| 午夜在线视频观看日韩17c| 久久久久久久久久久久久久一区| 久久久不卡网国产精品一区| 欧美激情国产日韩| 国产一区二区三区精品久久久| 精品av久久707| 巨胸喷奶水www久久久免费动漫| 欧美亚洲一级| 欧美日韩在线直播| 激情欧美一区二区三区在线观看| 亚洲国产成人在线视频| 亚洲欧美日韩精品久久亚洲区| 久久综合久久综合久久| 国产亚洲aⅴaaaaaa毛片| 亚洲国产一区二区三区高清| 久久久久天天天天| 国内外成人免费激情在线视频网站 | 欧美国产三级| 一区免费视频| 久久综合五月天婷婷伊人| 国产精品视频网址| 亚洲一区二区在线观看视频| 欧美一区成人| 狠狠色综合播放一区二区| 久久久久**毛片大全| 亚洲免费观看高清在线观看| 久久久蜜臀国产一区二区| 国产精品激情偷乱一区二区∴| 加勒比av一区二区| 久久黄色小说| 国产一区二区精品久久| 久久婷婷国产麻豆91天堂| 亚洲免费电影在线观看| 欧美日韩国产专区| 亚洲女性裸体视频| 国内一区二区在线视频观看| 欧美成人免费大片| 一区二区三区四区在线| 黑人巨大精品欧美黑白配亚洲| 猫咪成人在线观看| 午夜精品久久| 日韩一区二区电影网| 伊人伊人伊人久久| 国产精品久久久久77777| 欧美精品网站| 中文精品99久久国产香蕉| 国产精品亚洲片夜色在线| 你懂的视频一区二区| 亚洲欧美韩国| 亚洲字幕一区二区| 99在线热播精品免费99热| 国内精品久久久久影院 日本资源| 猛干欧美女孩| 久久久水蜜桃| 久久久久久黄| 久久久久九九九| 久久久久五月天| 亚洲一区二区成人| 亚洲一级电影| 欧美一区2区三区4区公司二百 | 欧美国产视频日韩| 久久久久久69| 久久久久久久尹人综合网亚洲| 欧美一区二区三区四区高清 | 国产噜噜噜噜噜久久久久久久久| 欧美国产日韩一区二区| 久久伊伊香蕉| 欧美片在线观看| 国产精品国产a级| 国产裸体写真av一区二区| 国产一区二区视频在线观看| 国产日韩欧美不卡| 一区二区在线不卡| 在线视频中文亚洲| 久久精品99国产精品酒店日本| 久久精品国产亚洲一区二区三区| 久久亚洲精品欧美| 欧美日韩综合另类| 国产日本欧美视频| 亚洲免费观看高清完整版在线观看熊| 亚洲精品免费在线播放| 欧美在线欧美在线| 麻豆精品视频在线观看| 国产精品va| 亚洲精品欧洲精品| 久久久精品国产免费观看同学| 欧美片网站免费| 亚洲国产精品va在线观看黑人| 亚洲欧美精品一区| 欧美午夜不卡影院在线观看完整版免费 | 久久中文在线| 国模 一区 二区 三区| 亚洲综合电影一区二区三区| 欧美精品1区2区| 国产精品日韩在线观看| 欧美中文字幕视频在线观看| 亚欧成人在线| 国产精品毛片在线| 亚洲婷婷在线| 欧美天堂亚洲电影院在线播放| 亚洲国产三级在线| 欧美另类女人| 午夜天堂精品久久久久| 国产午夜亚洲精品羞羞网站 | 一区二区三区在线视频观看| 亚洲欧美国产77777| 国产精品久久久久久久久久久久久久| 99日韩精品| 在线欧美视频| 国产精品久久久一本精品| 先锋资源久久| 亚洲伦理精品| 国产在线欧美日韩| 欧美精品一区三区在线观看| 国产精品99久久久久久宅男 | 亚洲男同1069视频| 国产精品国产精品| 西瓜成人精品人成网站| 国产免费成人在线视频| 免费久久99精品国产自在现线| 黄色精品在线看| 国产精品色一区二区三区| 亚洲图片激情小说| 国产日产高清欧美一区二区三区| 欧美好骚综合网| 亚洲欧美日韩视频二区| 国产亚洲va综合人人澡精品| 欧美精品免费视频| 欧美一区视频在线| 亚洲国产精品久久久久秋霞蜜臀 | 国产精品久久国产愉拍| 午夜精品久久久久久久久久久久久 | 国模一区二区三区| 麻豆免费精品视频| 亚洲影视综合| 欧美一区二区三区在线看| 国产在线视频欧美| 欧美日韩精品免费看| 午夜一区二区三区不卡视频| 亚洲成色www久久网站| 国产精品午夜av在线| 欧美国产日韩二区| 欧美日韩中文在线| 欧美日韩第一页| 欧美日韩1区| 国产日韩欧美综合在线| 国产欧美一区二区三区久久人妖|