js對象字面量知識總結(jié)

js中創(chuàng)建一個自定義對象有兩種方法概作,一種是使用new腋妙,另一種是使用對象字面量形式,至于構(gòu)造函數(shù)模式讯榕、工廠模式骤素、原型模式匙睹、組合模式、寄生模式济竹、es6中的class痕檬、Object.create()等等,都不過是這兩種方法的組合應(yīng)用

在創(chuàng)建一個對象字面量前送浊,要記住幾點:

  1. 這種對象不是一個構(gòu)造函數(shù)梦谜,不能使用new進行實例化

  2. 它是引用類型,也就意味著對象名是一個指針袭景,當(dāng)你把對象名賦值給另一個變量時唁桩,你在新變量上所做的任何操作都會影響源對象

    var obj={
      id:123
    }
   var b=obj
   b.id=456;
   console.log(obj.id) //456
  1. 對象中的所有成員默認(rèn)是公開的,如果想實現(xiàn)私有成員耸棒,只能采用es6的Symbo來定義一個成員名朵夏,然后采用export模塊化來達到隔離效果。

一榆纽、對象字面量語法

var person={
    name:'小王',
    age:18,
    _pri:233
}

-成員名稱的單引號不是必須的
最后一個成員結(jié)尾不要用逗號仰猖,不然在某些瀏覽器中會拋出錯誤
成員名相同會發(fā)生什么?
es5普通模式下后定義的會覆蓋前面定義的奈籽,嚴(yán)格模式則會報錯,es6則不管什么模式都采用后面的覆蓋前面的

成員名可以是動態(tài)變量嗎饥侵?
es5只能在對象字面量表達式申明以后再添加

var dynamicVar="dyna";
var person={
}
person[dynamicVar]='123';
console.log(person[dynamicVar])

es6則更符合使用場景,可在表達式內(nèi)創(chuàng)建動態(tài)的成員名

var dynamicVar="dyna";
var person={
  [dynamicVar]:'test'
}
console.log(person[dynamicVar])

es6中如果想使用表達式外面的變量名作為成員名衣屏,變量的值作為成員值躏升,可進一步簡寫為

var dynamicVar="dyna";
var person={
  dynamicVar, //這是一個語法糖,js引擎會解釋為dynamicVar:'dyna'
  age:15
}
console.log(person.dynamicVar)

注意:此時不能采用person[dynamicVar]方式訪問狼忱,因為這句話js引擎會解釋為person['dyna']膨疏,對象中沒有dyna屬性,肯定就是undefined

可以采用new person()的方式使用嗎钻弄?
肯定是不可以佃却,new關(guān)鍵字后面必須是一個構(gòu)造函數(shù)才行,對象字面量哪來的構(gòu)造函數(shù)

二窘俺、對象成員配置

對象申明后饲帅,會默認(rèn)為內(nèi)部的每個成員(屬性或方法)生成一些隱藏屬性,這些隱藏屬性是可以讀取和可配置的:

Object.getOwnPropertyDescriptor()或getOwnPropertyDescriptor()-讀取成員的隱藏屬性

Object.definePropertype或Object.defineProperties----設(shè)置成員的隱藏屬性

相應(yīng)的隱藏信息如下:

1.configurable

是否可以刪除某個成員瘤泪,默認(rèn)為true,需要注意的是灶泵,如果該屬性如果定義為false,后續(xù)又定義為true的話會報錯

Object.defineProperty(person,'name',{
  configurable:false
})
Object.defineProperty(person,'name',{
 configurable:true
})
2. writable

成員是否可寫,默認(rèn)為true

Object.defineProperty(person,'name',{
  writable:false
})
person.name='小李'; //屬性不可寫对途,嚴(yán)格模式下會報錯
console.log(person.name); //輸出小王赦邻,說明上面一句無效
3. enumerable

成員是否可被枚舉,默認(rèn)為rue,該屬性主要是用來防范Object.keys()for in的实檀,也就是說該屬性設(shè)置對于Object.getOwnPropertyNames()方法是無效的惶洲。

使用相應(yīng)的枚舉方法按声,輸出的結(jié)果是一個數(shù)組,那么數(shù)組中元素的順序是按什么規(guī)則組織的呢湃鹊?

在es5中并沒有明確這一點儒喊,各個瀏覽器有自己的實現(xiàn)镣奋,es6中采用Object.keys()和for in方法時還是沒有明確币呵,但采用Object.getOwnPropertyNames()方法枚舉時,有了相應(yīng)的標(biāo)準(zhǔn):

最先放入數(shù)組中的是數(shù)值型的成員名侨颈,按升序排列余赢;
其次是其它類型的,按添加的先后順序排列

var obj={

3:'我是1',

1:'我是1',

b:'我是b',

a:'我是a'

}

var names=Object.getOwnPropertyNames(obj);
console.log(names) //["1","3","b","a"]
4. get與set

讀寫成員時調(diào)用的函數(shù)哈垢,默認(rèn)為undefined

在文章最開始處的對象定義中妻柒,我們創(chuàng)建了一個_pri成員,表示這個成員應(yīng)在內(nèi)部讀取耘分,下劃線只是一個標(biāo)記符举塔,并不能限制該成員只能在對象內(nèi)部訪問。接下來我們來封裝一個屬性讀寫器對_pri成員進行讀取求泰,讀寫器名稱隨意取央渣,這里叫pri只是為了可讀性

Object.defineProperty(person,'pri',{
  get:function(){
    //做一些其它操作
    console.log('準(zhǔn)備獲取_pri的值')
    return _pri;
  },
  set:function(newValue){
    _pri =newValue
  }
})
person.pri='456';
console.log(person.pri);

如果只有g(shù)et則表示屬性值是只讀的,只有set表示只能寫渴频。

屬性讀寫器最常用的場景就是在讀取或?qū)懭雽傩郧翱梢愿綆У淖鲆恍┎僮餮康ぃ_到更好的封裝性

三、對象保護

禁止添加成員

Object.preventExtensions()該方法用于阻止向?qū)ο筇砑映蓡T,使用Object.isExtensible()`判斷對象是否可添加成員

Object.preventExtensions(person);
//添加成員無效卜朗,非嚴(yán)格模式下什么都不會發(fā)生拔第,嚴(yán)格模式下會報錯
person.bankAccount='中國農(nóng)業(yè)銀行'
//依然可以刪除成員,證明了preventExtensions方法只能阻止添加方法
delete person.age;
console.log(person.age) //undefined场钉,表明刪除成功了

禁止添加蚊俺、刪除成員

Object.seal()用來阻止添加或刪除成員,判斷對象是否是密封的可采用Object.isSealed()

禁止任何操作

使用Object.freeze()方法后逛万,除了不能添加刪除成員春叫,連成員的賦值都會失效,但是寫入屬性(上面set定義的)依然是有效的

四泣港、其它技巧

實現(xiàn)繼承

Object.create(person)可產(chǎn)生一個具有繼承特性的新對象暂殖,但是需要注意的是,父對象的引用類型成員是和子對象共享的当纱,當(dāng)子對象修改引用類型的成員時呛每,父對象的該成員也會同步發(fā)生變化

var person={
  name:'小王',
  age:18,
  _pri:233,
  gf:['豆得兒','張G','TFb']
}
var child=Object.create(person);
child.gf.splice(0,1); //跟豆得兒分手了
console.log(person.gf.length) //父類的gf也變成2了,父子共享女友坡氯,尼瑪晨横,太亂了

es6中的Object.setPrototypeOf(obj, prototype)方法可將已有的對象變成繼承關(guān)系洋腮,其內(nèi)部原理也跟Object.create一樣,都是將子對象的prototype指向父對象手形,該方法實現(xiàn)的繼承依然有父子對象共享了引用類型成員的問題啥供。

var person={
   age:15
 }
 var man={
     
 }
Object.setPrototypeOf(man,person)
console.log(Object.getPrototypeOf(man)===person) //true
console.log(man.age); //15

重寫父對象的成員
直接在子對象中定義一個同名的成員即可

子對象中訪問父對象的成員

super關(guān)鍵字是es6新增的,它是一個指針库糠,指向當(dāng)前對象的原型伙狐,也就是父對象

var person={
   age:15,
   testMethod(){
     console.log('我是父類方法')
   }
 }
 var man={
    //重寫父類方法
    testMethod(){
      console.log('我是子類方法')
      super.testMethod();
    }
 }
Object.setPrototypeOf(man,person)
man.testMethod();

需要注意的是,如果兩個對象不是繼承關(guān)系瞬欧,使用super關(guān)鍵字會報錯

實現(xiàn)jquery.extend
jquery.extend是一個典行的對象混入贷屎,所謂對象混入,就是將n個對象(為了便于表述艘虎,直接叫做輸入對象)組合成一個新對象唉侄,新對象具有各個輸入對象的特征,這在軟件設(shè)計模式中叫做裝飾器模式野建,在es6以前需要自己實現(xiàn)属划,核心代碼如下:

function mixins(target,sourceArr){
  sourceArr.forEach(function(source){
     Object.keys(source).forEach(function(item){
       target[item] = source[item]
     })
  })
  return target
}
var obj1={
  name:'123'
}
var obj2={
  id:100
}
var obj3={
  meth(){
    console.log('haha')
  }
}
var target=mixins(obj1,[obj2,obj3])
target.meth()

上面的代碼實現(xiàn)了一個簡易版的jquery.extend的淺拷貝模式(也就是deep參數(shù)為false時的功能),如果多個對象成員同名候生,則后面的會覆蓋前面的同眯,該代碼如果要在正式環(huán)境使用,還需要加不少的判斷代碼陶舞,但是在es6中一句話就可以實現(xiàn)mixins()函數(shù)的功能嗽测。

var target=Object.assign(obj1,obj2,obj3)

需要注意的一點就是輸入對象中使用了get修飾符,這時后會有一個轉(zhuǎn)換,方法名變成了新對象的屬性名肿孵,其值為get修飾符方法中的返回值

var obj1={
      name:'123'
    }
    var obj2={
      id:100
    }
    var obj3={
      get getMethod(){
        return '123'
      },
      meth(){
        console.log('haha')
      }
    }
    var target=Object.assign(obj1,obj2,obj3)
    console.log(target.getMethod) //target.getMethod()會報錯唠粥,原因是發(fā)生了轉(zhuǎn)換
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市停做,隨后出現(xiàn)的幾起案子晤愧,更是在濱河造成了極大的恐慌,老刑警劉巖蛉腌,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件官份,死亡現(xiàn)場離奇詭異,居然都是意外死亡烙丛,警方通過查閱死者的電腦和手機舅巷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來河咽,“玉大人钠右,你說我怎么就攤上這事⊥罚” “怎么了飒房?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵搁凸,是天一觀的道長。 經(jīng)常有香客問我狠毯,道長护糖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任嚼松,我火速辦了婚禮嫡良,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惜颇。我一直安慰自己皆刺,他們只是感情好少辣,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布凌摄。 她就那樣靜靜地躺著,像睡著了一般漓帅。 火紅的嫁衣襯著肌膚如雪锨亏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天忙干,我揣著相機與錄音器予,去河邊找鬼。 笑死捐迫,一個胖子當(dāng)著我的面吹牛乾翔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播施戴,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼反浓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赞哗?” 一聲冷哼從身側(cè)響起雷则,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肪笋,沒想到半個月后月劈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡藤乙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年猜揪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坛梁。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡而姐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罚勾,到底是詐尸還是另有隱情毅人,我是刑警寧澤吭狡,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站丈莺,受9級特大地震影響划煮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缔俄,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一弛秋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俐载,春花似錦蟹略、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至状婶,卻和暖如春意敛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背膛虫。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工草姻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稍刀。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓撩独,卻偏偏與公主長得像,于是被迫代替她去往敵國和親账月。 傳聞我的和親對象是個殘疾皇子综膀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容