內部屬性在咱們瞭解對象原型及環境變量時都有遇到過,但是畢竟看不到摸不着,很難更加深刻的瞭解它的工做流程和做用,最近在chrome當中查看對象結構時,看到了釋放出來的一些內部屬性,這些之前大概都是概念,那麼既然能看到,就讓咱們來探索一下吧~
此屬性儲存在函數對象中,我記得從chrome 62開始我就發現這個屬性了,具體哪一個版本你們能夠google,如今咱們把它給打印出來看一下.javascript
這是一個不訪問外部變量的函數,因此Scopes中只儲存了Global全局對象。前端
還記得做用域鏈嗎(若是不記得,請點擊這裏看前半部分)?
從前日後分別是 [函數本身的變量對象,.., .., Global] 相似於這樣依次向後(上)查找這個執行環境所使用到
的變量對象。java
在上面的文章說過,javascript在開始執行時,會通過兩個階段,預編譯->代碼執行,在v8中代碼執行階段運行的是機器碼
,CPU能夠直接接收,
能夠說,在javascript代碼執行前都會通過複雜的代碼分割,生成抽象語法樹(AST),編譯解析與優化等操做,[[Scopes]]正是這其中的產物。下面說
下它造成的流程。react
永遠都是
Global全局對象,向前依次是祖先->父級。注意,這時只是在第一個階段,js引擎並無執行你的操做。(總之全部的髒活累活都要在第一個階段完成,以保證js引擎執行的最高效率)執行環境
(函數)的[[Scopes]]屬性,並把自身的變量對象加入到前端(unshift),造成做用域鏈
,這樣從頭至尾的變量對象,構成了偉大的做用域。須要注意的是,並非全部的父級做用域的變量都進行存儲,而只會存儲當前函數所使用到的變量。因此咱們進行這樣的操做是查看不到父級變量的.chrome
var a = 1; function fun(){ var b = 1; const p = ()=>{} console.dir(p) } fun();
函數p當中並沒用使用到父級函數中的變量b,因此[[Scopes]]只有Global對象(注意,由於Global對象永遠存在,而且是引用,因此不會出現這種狀況),
我認爲這也是一種優化手段,能夠極大減小內存的使用。segmentfault
咱們換種寫法:數組
var a = 1; function fun(){ var b = 1; const p = ()=>{ var c = 1; const f = ()=>{ console.log(b,c) } console.dir(f) } p(); } fun();
咱們引用了父級做用域中的變量,並打印出來,在編譯階段,編譯器把他們加入到了[[Scopes]]中。瀏覽器
此屬性,咱們不可去訪問與修改它,目前只能在控制檯中點擊查看.dom
這個很容易理解,相似於debugger功能,能夠很容易的查找到此函數的代碼位置,好比咱們以React爲例,查看 React.Component函數位置.函數
能夠看到,key右側的可點擊部分,表示函數在react-dom.min.js第34行,咱們點進去查看,暈了,代碼被混淆了...
對於這個屬性,咱們之後能夠大大減小console的使用啦
遵循ECMAScript標準,someObject.[[Prototype]] 符號是用於指向 someObject的原型。從 ECMAScript 6 開始,[[Prototype]]
能夠用Object.getPrototypeOf()和Object.setPrototypeOf()訪問器來訪問。這個等同於 JavaScript 的非標準但許多瀏覽器實現的屬性
__proto__。咱們常常使用Object.prototype.toString來判斷對象類型,toString就是把當前的這個屬性轉換成字符串返回出去了.
這個內部屬性,表示對象的原型鏈,相似與[[Scopes]]也是一個數組格式.
var b = {a:1}; function o(a){ this.b = a; } o.prototype = { c:3; } b.__proto__ = new o(2); console.log(b.a,b.b,b.c); //1 2 3
此時原型鏈關係是這樣的:
貌似還有不少內部屬性,一時想不起來(若是發現,之後會更新),你們有知道的,能夠發表評論。