内部属性在咱们了解对象原型及环境变量时都有遇到过,但是毕竟看不到摸不着,很难更加深刻的了解它的工做流程和做用,最近在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
此时原型链关系是这样的:
貌似还有不少内部属性,一时想不起来(若是发现,之后会更新),你们有知道的,能够发表评论。