【问题标题】:Weird behavior when declaring class property with semicolon用分号声明类属性时的奇怪行为
【发布时间】:2018-02-17 12:43:25
【问题描述】:
class SomeClass {
  x: 5;
  y = 10;
}

const c = new SomeClass();
alert(c.x + ' : ' + c.y); 

为什么代码可以编译但c.x的值是未定义的?

用:声明类属性有什么作用?

【问题讨论】:

  • 这不是 ES6,我也不相信 x: 5; 是任何形式的提议。
  • 这不是 js 中有效的类声明。
  • y = 10; 语句是 this Stage 3 Proposal 的一部分。
  • 可能是某种语言扩展中的类型注解,但绝对不是合法的JS

标签: javascript es6-class ecmascript-next


【解决方案1】:

关于x: 5 部分,虽然这是一个有效的javascript代码,但并没有多大用处。
这是一个 javascript label,它主要在循环上下文中使用(如果有的话)。

所以回答你的问题:

为什么代码可以编译

因为从技术上讲,这是一个有效的 javascript 代码(但不是有效的 class 字段)。

但是c.x 的值是未定义的

因为x 是标签而不是类字段。

用:声明类属性有什么作用

你得到一个标签而不是一个类字段。


附录
另一个常见的错误是这个块代码:
class SomeClass {
  z = () => {
    x: 5;
  };
}

你会认为z() 会返回一个带有x 键的对象:

`{x:5}`

但实际上你有一个标签为x 的函数,它只运行5 的表达式。

为了完整起见,解决方法是添加显式返回和另一组花括号

() => {return {x: 5}}

或者只是用括号括起来

() => ({x: 5})

编辑
作为以下 cmets 的后续行动:
为了清楚起见,您的代码可以在我测试的几个环境以及 stack-sn-ps 上编译,如下所示:

class SomeClass {
  x: 5;
  y = 10;
}

const c = new SomeClass();
console.log(c.x + ' : ' + c.y); 

【讨论】:

  • 在块内部({ … },看起来像一个对象字面量)它可能是有效的代码,但没有一个标签绝对不是 class 正文的一部分。
  • @Bergi “一个标签作为类主体的一部分肯定是无效的” 我在哪里说的?我写道:“虽然这是一个有效的 javascript 代码,但它并没有多大用处……”。这是有效的 javascript 代码,因此 babel 不会抱怨它(它当然会被忽略)。
  • 您说它是有效代码,但显然不是。 x: 5 部分类 不是有效代码。标记序列“x: 5”可以是对象文字的有效部分、字符串文字的有效部分,甚至是其自身的有效语句,对于这个问题来说根本不重要。 OP发布的代码不可编译。
  • 我不想在这里争论,但我想清楚(也许从我的错误中吸取教训)。 OP问:“为什么代码是可编译的,但c.x的值是未定义的?”。你不能忽略代码是可编译的事实(你也可以检查babel generates它是如何没有错误的)。我仍然认为它是有效代码,因为没有错误,它是有用的代码吗?当然不是。
  • 所以这是一个“有效”的 JS 代码,在这种情况下毫无意义。编译器/linter 应该能够识别上下文并触发错误,而不是默默地忽略它......
【解决方案2】:

代码不是有效的 ES6。

您似乎正在使用 babel“编译”,并且无意中启用了 flow 语法扩展(以及第二行的 class properties)。在流程中,x: 5 是 class field type annotation。当然,5 作为一种类型没有意义,但显然它们允许非常任意的表达式。

【讨论】:

  • 我不确定你是否在这里,因为如果这是真的,这段代码应该编译:class SomeClass { x: number = 5; } 但不幸的是它没有。
猜你喜欢
  • 2017-04-10
  • 2016-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多