为啥 ES6 类语法控制台的日志记录与 ES5 类语法不同?

Posted

技术标签:

【中文标题】为啥 ES6 类语法控制台的日志记录与 ES5 类语法不同?【英文标题】:Why would the ES6 class syntax console log differently than an ES5 class syntax?为什么 ES6 类语法控制台的日志记录与 ES5 类语法不同? 【发布时间】:2016-09-11 15:23:41 【问题描述】:

我正在尝试更多地学习 ECMAScript 6 并更好地继承。

问题:当我在控制台注销 bobdaisy 时,它们会有所不同。 bob 记录 __proto__ 下的原型,并显示run:true; 的构造函数。在 ES6 实现中 daisy 没有 __proto__ 但是,它仍然有 isRunning 可访问的。为什么?

var Man = (function()
  "use strict";
  function Man() 
    this.run = true
  

  Man.prototype.isRunning = function() 
    console.log('yesss imma run');
  ;

  return Man;
)();

var bob = new Man();
console.log(bob);

class Woman 
  constructor()
    this.run = true;
  

  isRunning() 
    console.log('yess imma run');
  


var daisy = new Woman();
console.log(daisy);

【问题讨论】:

这真的是在a function definition? 中对use strict 的正确解释吗?我认为这是 ecmascript-6 (ES6) 代码,但您不是在比较 ES6 严格与非严格,而不是 ES5 VS ES6? 我在 jsfiddle 上遇到了这种行为,但是 codepen 使用 _proto_: codepen.io/anon/pen/gryyWg 记录两者 控制台的行为不规范。它完全依赖于实现。 啊,当然有道理 改为使用console.dir(daisy) 【参考方案1】:

这是因为 ES6 类中定义的方法是不可枚举的。在 Man 对象中,isRunning 是可枚举的,但在 Woman 中不是。 Chrome 有一种处理控制台日志的特定方式。取决于可枚举属性的存在与否会影响显示。

控制台显示的差异微不足道,但它显示了使用 ES6 Class 构建类的方式的有趣差异。为了更清楚地看到它,您可以尝试使 Man isRunning 不可枚举或 Woman isRunning 可枚举,它应该在控制台中提供相同的输出。对于 Man 中的不可枚举,就像这样:

var Man = (function() 
     "use strict";

     function Man() 
       this.run = true
     

     Object.defineProperty(Man.prototype, 'isRunning', 
       value: function() 
         console.log('yesss imma run');
       ,
       enumerable: false
     );

     return Man;
   )();

   
   bob = new Man();
   console.log(bob);

   class Woman 
     constructor() 
       this.run = true;
     

     isRunning() 
       console.log('yess imma run');
     
   

   daisy = new Woman();
   console.log(daisy);

或在女人中可枚举:

   var Man = (function() 
     "use strict";

     function Man() 
       this.run = true
     

     Man.prototype.isRunning = function() 
       console.log('yesss imma run');
     ;

     return Man;
   )();


   bob = new Man();
   console.log(bob);

   class Woman 
     constructor() 
       this.run = true;
     

     isRunning() 
       console.log('yess imma run ');
     
   
   Object.defineProperty(Woman.prototype, 'isRunning', 
     enumerable: true
   );
   daisy = new Woman();
   console.log(daisy);

编辑:

请注意,ES6 的初始草案默认将 enumerable 设置为 true,但它已更改,这是一个设计决定。您可以在此处查看导致该决定的讨论: https://esdiscuss.org/topic/classes-and-enumerability

基本上,原生原型通常具有不可枚举的方法,因此与用户定义的类具有相同的行为是有意义的。

该决定是在第 32 版草案中引入的。 http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#february_2_2015_draft_rev_32

【讨论】:

我可以问一下,为什么在使用 ES6 类语法时原型方法设置为可枚举的 false 吗? ***.com/questions/14984533/…

以上是关于为啥 ES6 类语法控制台的日志记录与 ES5 类语法不同?的主要内容,如果未能解决你的问题,请参考以下文章

重学ES6:ES5和ES6中Class类的相同与不同

ES6-18:class类及其继承

ES6类文字中的IIFE

ES6更易于继承的类语法

ES6更易于继承的类语法

ES5与ES6的一些语法对照