【问题标题】:ES6 getter/setter with arrow function带有箭头功能的 ES6 getter/setter
【发布时间】:2016-02-22 23:45:55
【问题描述】:

我正在使用 babel6,对于我的宠物项目,我正在为 XMLHttpRequest 创建一个包装器,用于我可以使用的方法:

open = (method, url, something) => {
  return this.xhr.open(method, url, something);
}

但是对于属性箭头功能不起作用

这行得通:

get status() { return this.xhr.status; }

但是我不能用

get status = () => this.xhr.status;

这是故意的吗?

【问题讨论】:

  • 你不需要大括号或回车;你可以说(method, url, something) => this.xhr.open(method. url, something)
  • get 是对象文字或类定义的一部分,变量赋值不是。为什么你认为他们应该工作一样?
  • status => this.xhr.status (c# 7 syntaxe) 或者 get status() => this.xhr.status 确实是一个很好的可读性语法糖,但 Javascript 而不是 Typescript 不(还没有?)支持它
  • 我的生活中非常需要这个!!!

标签: ecmascript-6 babeljs


【解决方案1】:

根据 ES2015 语法,a property on an object literal 只能是以下四种之一:

属性定义

  • 标识符参考
  • PropertyName : AssignmentExpression
  • 方法定义

这些类型中唯一允许使用前导get 的是MethodDefinition

方法定义

  • PropertyName ( StrictFormalParameters ) { FunctionBody }
  • GeneratorMethod
  • get PropertyName ( ) { FunctionBody }
  • set PropertyName (PropertySetParameterList ) { FunctionBody }

如您所见,get 表单遵循非常有限的语法,必须是表单

get NAME () { BODY }

语法不允许get NAME = ... 形式的函数。

【讨论】:

  • 感谢您的帮助,我接受您的回答。你知道在哪里定义 getter/setter 不能用于赋值吗?只是好奇。
  • @GaborDolla 已编辑以引用 ECMAScript 规范中的对象文字语法。
【解决方案2】:

接受的答案很棒。如果您愿意使用普通函数语法而不是紧凑的“箭头函数语法”,那是最好的。

但也许你真的很喜欢箭头函数;也许您出于其他原因使用箭头函数普通函数语法无法替代;您可能需要不同的解决方案。

例如,我注意到 OP 使用 this,您可能想要 bind this lexically; aka "non-binding of this"),并且箭头函数非常适合该词法绑定。

您仍然可以通过 Object.defineProperty 技术将箭头函数与 getter 一起使用。

{
  ...
  Object.defineProperty(your_obj, 'status', { 
     get : () => this.xhr.status 
  });
  ...
}

参见 object initialization technique (aka get NAME() {...})defineProperty technique (aka get : ()=>{}) 的提及。至少有一个显着差异,使用defineProperty需要变量已经存在:

现有对象上定义一个getter

即对于Object.defineProperty,您必须确保your_obj(在我的示例中)存在并保存到一个变量中(而对于object-initialization,您可以在对象初始化中返回一个对象文字:{..., get(){ }, ... })。更多信息Object.defineProperty specifically, here

Object.defineProperty(...) 似乎具有与get NAME(){...} 语法相当的浏览器支持;现代浏览器,IE 9。

【讨论】:

  • 很聪明,但它最终比简单得多:get status() { return this.xhr.status; }
  • @devuxer 我同意它太冗长了。但为了清楚起见,您的 this 必须 是定义 get status() { ... } 的对象。但是 my this 可能是别的东西,由于词法绑定的差异,对吧?
  • 同意...虽然在实践中,我还没有遇到过 this 不是我想要的 get 访问器的情况。 (箭头函数的this 绑定优势似乎在传递函数时发挥了作用,就像事件处理程序和回调一样。)
  • 我同意,我经常使用粗箭头 + 词法绑定 ()=>{} 来传递我传递给 Promise 的回调,例如 $http(...).then((promise_result)=> this...}))。如果我不使用胖箭头,this 将代表全局Window 对象;不是很有用。但我很少(从不?)使用()=>{} 作为“获取访问器”的函数,正如你所说的......至少get() 内部的this 将代表定义get() 的对象(其中已经比Window 更有用了;所以没有必要使用胖箭头函数!)
  • defineProperty 方法在循环中很有用。现在我只是用它来从包含对象的对象中公开一些对象的属性。
猜你喜欢
  • 2020-03-17
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2017-12-25
  • 2019-12-17
  • 2017-10-14
相关资源
最近更新 更多