本篇開始看下js物件原型[[prototype]]
。
js中的物件有一種特殊的內建屬性[[prototype]]
,其實就是對於其他物件的引用。幾乎所有的物件在建立時都[[prototype]]
屬性都會被賦予乙個非空的值。
var obj =
console.
log(obj.a)
;// 2
var newobj = object.
create
(obj)
;console.
log(newobj.a)
;// 2
上例的newobj
物件的[[prototype]]
屬性指向obj
物件。
當試圖引用物件的屬性時會觸發[[get]]
操作,例如obj.a
和newobj.a
。對於預設的[[get]]
操作來說,第一步是檢查物件本身是否有這個屬性,如果有的話就使用它。如果物件本身沒有這個屬性,就需要使用到物件的內建屬性[[prototype]]
了,[[get]]
操作會訪問物件的[[prototype]]
鏈,對於上例的newobj.a
操作而言就是會繼續訪問其原型鏈上層的obj
物件。
現在我們明白訪問物件的屬性時,會先查詢物件本身,如本身沒有對應屬性時,會向該物件的原型鏈上層物件查詢,找到則返回該屬性的值,如始終沒有找到,則返回undefined
。
那麼這個始終沒有找到的盡頭在哪?就在object.prototype
。它是js中所有物件的源頭,object.prototype
的再上一層也有,但是null
了。
不光訪問物件的屬性可能會查詢其原型鏈,為物件屬性設定值時同樣也可能會查詢該物件的原型鏈。
通常為物件屬性設定值我們採用=
賦值操作符來進行,當為物件obj的foo屬性設定值時:
obj.foo =
"bar"
;
// 1.
var parentobj =
;var obj = object.
create
(parentobj)
;obj.foo =5;
console.
log(obj.foo)
;// 5
// 2.
var parentobj =
;object.
defineproperty
(parentobj,
"foo",)
;var obj = object.
create
(parentobj)
;obj.foo =5;
console.
log(obj.foo)
;// 10 無法修改已有屬性或在obj物件上建立遮蔽屬性 非嚴格模式時忽略obj.foo = 5;操作,嚴格模式時直接報錯
// 3.
var parentobj =
,set
foo(val)
}parentobj.foo =10;
console.
log(parentobj.foo)
;// 40
var obj = object.
create
(parentobj)
;obj.foo =3;
console.
log(obj.foo)
;// 12 繼續呼叫原型鏈上層物件上 setter,
console.
log(obj.
hasownproperty
("foo"))
;// false 並且foo還不會被新增到obj物件上
如果希望在第2和第3種情況也能遮蔽foo屬性,就不能使用=
賦值操作符,而應使用object.defineproperty()
來向obj物件新增foo。
// 2.
var parentobj =
;object.
defineproperty
(parentobj,
"foo",)
;var obj = object.
create
(parentobj)
;object.
defineproperty
(obj,
"foo",)
console.
log(obj.foo)
;// 5 這回可以在obj物件建立遮蔽屬性foo了,值也為最新值 5
// 3.
var parentobj =
,set
foo(val)
}parentobj.foo =10;
console.
log(parentobj.foo)
;// 40
var obj = object.
create
(parentobj)
;object.
defineproperty
(obj,
"foo",)
console.
log(obj.foo)
;// 7
你看,所以如果確實想改,也是有辦法的,用object.defineproperty()
就行。
你不知道的javascript(二)
1.詞法作用域 就是定義在詞法階段的作用域,作用域查詢會在找到第乙個匹配的識別符號時停止。在多層的巢狀作用域中可以定義同名的標識 符,這叫作 遮蔽效應 內部的識別符號 遮蔽 了外部的識別符號 拋開遮蔽效應,作用域查詢始終從 執行時所處的最內部作用域開始,逐級向外或者說向上進行,直到遇見第乙個匹配的識...
你不知道的JavaScript (上)
一 編譯的原理主要分為三個步驟 1 分詞 詞法分析 這個步驟主要是將字串分解成有意義的 2 解析 語法分析 陣列巢狀形成結構樹。3 生成 將結構樹轉化為 的過程。二 作用域 引擎主要進行搜尋查詢編譯等過程,分為左查詢lhs和右查詢rhs 編譯器主要是進行 的生成,語法分析。作用域主要是 確定訪問許可...
你不知道的JavaScript 筆記
作用域是什麼?作用域的兩種工作模式 詞法作用域和動態作用域 1.查詢 作用域查詢會在找到第乙個匹配識別符號停止 2.欺騙詞法 eval 修改作用域 with 建立新的作用域 後果 導致js引擎在靜態分析時停止優化,導致效能下降 遵循最小授權原則 1.隱藏內部實現 2.規避衝突 3.立即執行函式 ii...