鲜为人知的javascript的内部属性

内部属性在咱们了解对象原型及环境变量时都有遇到过,但是毕竟看不到摸不着,很难更加深刻的了解它的工做流程和做用,最近在chrome当中查看对象结构时,看到了释放出来的一些内部属性,这些之前大概都是概念,那么既然能看到,就让咱们来探索一下吧~

[[Scopes]]

此属性储存在函数对象中,我记得从chrome 62开始我就发现这个属性了,具体哪一个版本你们能够google,如今咱们把它给打印出来看一下.javascript

clipboard.png

clipboard.png

这是一个不访问外部变量的函数,因此Scopes中只储存了Global全局对象。前端

还记得做用域链吗(若是不记得,请点击这里看前半部分)?
从前日后分别是 [函数本身的变量对象,.., .., Global] 相似于这样依次向后(上)查找这个执行环境所使用到的变量对象。java

在上面的文章说过,javascript在开始执行时,会通过两个阶段,预编译->代码执行,在v8中代码执行阶段运行的是机器码,CPU能够直接接收,
能够说,在javascript代码执行前都会通过复杂的代码分割,生成抽象语法树(AST),编译解析与优化等操做,[[Scopes]]正是这其中的产物。下面说
下它造成的流程。react

  1. 词法阶段会定义函数所用到的变量,加入到[[Scopes]]内部属性当中,它是一个数组,最后一位永远都是Global全局对象,向前依次是祖先->父级。注意,这时只是在第一个阶段,js引擎并无执行你的操做。(总之全部的脏活累活都要在第一个阶段完成,以保证js引擎执行的最高效率)
  2. 执行流进入,读取这个执行环境(函数)的[[Scopes]]属性,并把自身的变量对象加入到前端(unshift),造成做用域链,这样从头至尾的变量对象,构成了伟大的做用域。

须要注意的是,并非全部的父级做用域的变量都进行存储,而只会存储当前函数所使用到的变量。因此咱们进行这样的操做是查看不到父级变量的.chrome

var a = 1;
  function fun(){
      var b = 1;
      const p = ()=>{}
      console.dir(p)
  }
  fun();

clipboard.png

函数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();

clipboard.png

咱们引用了父级做用域中的变量,并打印出来,在编译阶段,编译器把他们加入到了[[Scopes]]中。浏览器

此属性,咱们不可去访问与修改它,目前只能在控制台中点击查看.dom

[[FunctionLocation]]

这个很容易理解,相似于debugger功能,能够很容易的查找到此函数的代码位置,好比咱们以React为例,查看 React.Component函数位置.函数

clipboard.png

能够看到,key右侧的可点击部分,表示函数在react-dom.min.js第34行,咱们点进去查看,晕了,代码被混淆了...

clipboard.png

对于这个属性,咱们之后能够大大减小console的使用啦

[[Prototype]]

遵循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

此时原型链关系是这样的:

clipboard.png

貌似还有不少内部属性,一时想不起来(若是发现,之后会更新),你们有知道的,能够发表评论。

相关文章
相关标签/搜索