你不知道的JavaScript之對象

對象

基本形式

  • 聲明形式(對象字面量)
var obj = {
  name: 'object',
  age: 25
}
  • 構(gòu)造形式
var obj = new Object({name: 'object', age: 25})

對象類型

對象是JavaScript的基礎(chǔ)铛碑。在JavaScript中一共有六種主要類型聂渊。

  • string
  • number
  • boolean
  • undefined
  • null
  • object

簡單基本類型(string衰伯、boolean、number浅役、null和undefined)本身并不是對象漱受。typeof null 返回 'object' 是語言本身的一個(gè)bug。JavaScript沒打算修復(fù)這個(gè)bug荞彼,因?yàn)樾迯?fù)了這個(gè)bug會(huì)引發(fā)其他更多的bug冈敛。
原理是這樣的, 不同的對象在底層都表示為二進(jìn)制卿泽, 在JavaScript中二進(jìn)制前三位都為0的話會(huì)被判斷為object類型莺债,null的二進(jìn)制表示是全0,自然前三位也是0签夭,所以執(zhí)行typeof時(shí)會(huì)返回“object”齐邦。

內(nèi)置對象

  • String
  • Number
  • Boolean
  • Array
  • Function
  • Object
  • Date
  • RegExp
  • Error

這些內(nèi)置對象從表現(xiàn)形式來說很像其他語言中的類型(type)或者類(class),比如Java中的String類第租。
但是在JavaScript中措拇, 它們實(shí)際上只是一些內(nèi)置函數(shù)。 這些內(nèi)置函數(shù)可以當(dāng)作構(gòu)造函數(shù)(由new產(chǎn)生的函數(shù)調(diào)用)來使用慎宾,從而可以構(gòu)造一個(gè)對應(yīng)子類型的新對象丐吓。

對象內(nèi)容

對象的內(nèi)容是由一些存儲(chǔ)在特定命名位置的( 任意類型的)值組成的浅悉,我們稱之為屬性。
需要強(qiáng)調(diào)的一點(diǎn)是券犁, 當(dāng)我們說“ 內(nèi)容”時(shí)术健, 似乎在暗示這些值實(shí)際上被存儲(chǔ)在對象內(nèi)部,但是這只是它的表現(xiàn)形式粘衬。 在引擎內(nèi)部荞估, 這些值的存儲(chǔ)方式是多種多樣的, 一般并不會(huì)存在對象容器內(nèi)部稚新。 存儲(chǔ)在對象容器內(nèi)部的是這些屬性的名稱勘伺, 它們就像指針( 從技術(shù)角度來說就是引用)一樣,指向這些值真正的存儲(chǔ)位置褂删。

訪問對象的屬性:

var obj = {
  name: 'object',
  age: 25
}
obj.name
obj['name']

屬性和方法:

如果訪問的對象屬性是一個(gè)函數(shù)飞醉, 有些開發(fā)者喜歡使用不一樣的叫法以作區(qū)分。 由于函數(shù)很容易被認(rèn)為是屬于某個(gè)對象屯阀, 在其他語言中缅帘, 屬于對象( 也被稱為“ 類”)的函數(shù)通常被稱為“方法”,因此把“屬性訪問”說成是“方法訪問”也就不奇怪了蹲盘。
從技術(shù)角度來說股毫, 函數(shù)永遠(yuǎn)不會(huì)“ 屬于”一個(gè)對象, 所以把對象內(nèi)部引用的函數(shù)稱為“ 方法”似乎有點(diǎn)不妥召衔。
確實(shí)铃诬, 有些函數(shù)具有this引用, 有時(shí)候這些this確實(shí)會(huì)指向調(diào)用位置的對象引用苍凛。 但是這種用法從本質(zhì)上來說并沒有把一個(gè)函數(shù)變成一個(gè)“ 方法”趣席,因?yàn)閠his是在運(yùn)行時(shí)根據(jù)調(diào)用位置動(dòng)態(tài)綁定的,所以函數(shù)和對象的關(guān)系最多也只能說是間接關(guān)系醇蝴。

function foo() {
  return this.value
}

let anotherFoo = foo
let obj = {
  ownFoo: anotherFoo
}

console.log(foo === anotherFoo)
console.log(anotherFoo === obj.ownFoo)
// 這里的 foo anotherFoo obj.ownFoo 指向的都是同一個(gè)函數(shù) function () { return this.value }

復(fù)制對象

如何復(fù)制一個(gè)對象:

// 淺復(fù)制
let obj = {
  name: 'clone object',
  list: [1, 2, 3, 4, 5]
}
let anotherObj = obj
/**
 * 對于 obj 中的 name 屬性宣肚,anotherObj 會(huì)復(fù)制一份
 * 而對于 list 屬性,因?yàn)樗且弥涤扑ǎ?another 只是取得了對它的引用霉涨,實(shí)際上跟 obj 的list屬性指向的是同一個(gè)值
 */

obj.list.push(6)
anotherObj.list   // [1, 2, 3, 4, 5, 6]

ES6 通過 Object.assign() 實(shí)現(xiàn)了淺復(fù)制
Object.assign(targetObject, {}, {}, ...)

  • 第一個(gè)參數(shù)是目標(biāo)對象
  • 后面可以接多個(gè)參數(shù)對象

對于JSON安全( 也就是說可以被序列化為一個(gè)JSON字符串并且可以根據(jù)這個(gè)字符串解析出一個(gè)結(jié)構(gòu)和值完全一樣的對象)的對象來說,有一種巧妙的復(fù)制方法:

let anotherObj = JSON.parse(JSON.stringify())

JSON不安全值:

  • undefined惭适、 function笙瑟、 symbol( ES6+)和包含循環(huán)引用(對象之間相互引用,形成一個(gè)無限循環(huán))的對象都不符合 JSON結(jié)構(gòu)標(biāo)準(zhǔn)癞志,支持 JSON 的語言無法處理它們往枷。
  • JSON.stringify(..) 在對象中遇到 undefined、 function 和 symbol 時(shí)會(huì)自動(dòng)將其忽略,在數(shù)組中則會(huì)返回 null(以保證單元位置不變)错洁。
let foo = function () {}
let bar = JSON.parse(JSON.stringify(foo))

/**
 * SyntaxError: Unexpected token u in JSON at position 0
 * JSON.stringify(foo) 返回了 undefined
 * JSON.parse(undefined) 自然就報(bào)錯(cuò)了
 */

如何實(shí)現(xiàn)一個(gè)復(fù)制的通用方法:

function deepClone(target, source) {}

屬性描述符:writable秉宿、enumerable、configurable

let obj = {}
obj.defineProperty(obj, 'name', {
  value: 'propertyDescriptor',
  // 是否可以更改該值屯碴,通過obj.name 的方法修改值描睦,設(shè)為false則不可修改
  writable: false,
  // 是否可以遍歷
  enumerable: true,
  /**
   * 是否可配置,即是否可通過 obj.defineProperty 的方式重新配置
   * 設(shè)為false窿锉,不僅不能修改酌摇,也不能刪除該屬性
   */
  configurable: fasle,
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膝舅,一起剝皮案震驚了整個(gè)濱河市嗡载,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仍稀,老刑警劉巖洼滚,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異技潘,居然都是意外死亡遥巴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門享幽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铲掐,“玉大人,你說我怎么就攤上這事值桩“诿梗” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵奔坟,是天一觀的道長携栋。 經(jīng)常有香客問我,道長咳秉,這世上最難降的妖魔是什么婉支? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮澜建,結(jié)果婚禮上向挖,老公的妹妹穿的比我還像新娘。我一直安慰自己炕舵,他們只是感情好何之,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幕侠,像睡著了一般帝美。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天悼潭,我揣著相機(jī)與錄音庇忌,去河邊找鬼。 笑死舰褪,一個(gè)胖子當(dāng)著我的面吹牛皆疹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播占拍,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼略就,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晃酒?” 一聲冷哼從身側(cè)響起表牢,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贝次,沒想到半個(gè)月后崔兴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛔翅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年敲茄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片山析。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堰燎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笋轨,到底是詐尸還是另有隱情秆剪,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布翩腐,位于F島的核電站鸟款,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茂卦。R本人自食惡果不足惜何什,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望等龙。 院中可真熱鬧处渣,春花似錦、人聲如沸蛛砰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泥畅。三九已至荠诬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柑贞。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工方椎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钧嘶。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓棠众,卻偏偏與公主長得像,于是被迫代替她去往敵國和親有决。 傳聞我的和親對象是個(gè)殘疾皇子闸拿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360