ES6对象字面量中的简洁方法和非简洁方法

7
let module = {
     add: function(a, b){
        return parseInt(a) + parseInt(b);
     },

    sub(a, b){
        return parseInt(a) - parseInt(b);
    }
};

使用精简的方法语法(例如sub acove)与使用传统的非精简方法语法(例如add)相比,有哪些基本区别?

除了语法之间的明显差异外,精简和非精简方法本质上是相同的吗?


1
使用简洁方法有什么优缺点? - user544079
3
箭头函数写法:add = (a, b) => a + b - Tushar
2
@axiac 不是的。这只是对象初始化器的简写方法符号。 - Sebastian Simon
2
@Xufox,你没有,但是在这个fiddle中,arguments似乎工作得很好? - CertainPerformance
2
@CertainPerformance 我说这个_property_不存在。module.sub.hasOwnProperty("prototype") === falsemodule.sub.hasOwnProperty("arguments") === false等等。 - Sebastian Simon
显示剩余9条评论
1个回答

6
一个显著的区别是,简洁方法可以利用super关键字,而非简洁(又称:传统)方法则不能。当更改一个或多个对象的原型以帮助继承时,这变得相关。
为了演示这一点,请考虑以下要点:

const frenchPerson = {
  speak() {
    return 'Bonjour';
  }
};

const englishPerson = {
  speak() {
    return 'Hello';
  }
};

const multilinguist = {
  speak() {
    return `${super.speak()}, Hola`
  }
};

console.log(frenchPerson.speak()) // -> "Bonjour"
console.log(englishPerson.speak()) // -> "Hello"

Object.setPrototypeOf(multilinguist, frenchPerson);
console.log(Object.getPrototypeOf(multilinguist) === frenchPerson); // true

console.log(multilinguist.speak()); // -> "Bonjour, Hola"

Object.setPrototypeOf(multilinguist, englishPerson);
console.log(Object.getPrototypeOf(multilinguist) === englishPerson); // true

console.log(multilinguist.speak()); // -> "Hello, Hola"


解释:

  1. 首先注意所有对象,包括 frenchPersonenglishPersonmultilinguist,都使用了简洁的方法语法。

  2. 正如您所看到的,multilinguist 对象的名为 speak 的简洁方法使用了 super.speak() 来指向其对象原型(无论它是什么)。

  3. 在将 multilinguist 的原型设置为 frenchPerson 后,我们调用 multilinguistspeak() 方法,它会回复/记录:

    Bonjour, Hola

  4. 然后我们将 multilinguist 的原型设置为 englishPerson,并再次要求 multilinguist 进行 speak() - 这次它会回复/记录:

    Hello, Hola


multilinguistspeak() 方法不是简洁方法时会发生什么?

如果在 multilinguist 对象中使用非简洁的 speak() 方法,除了使用 super 引用外,它会返回:

语法错误

如下面的示例所示:

const englishPerson = {
  speak() {
    return 'Hello';
  }
};

const multilinguist = {
  speak: function() {           // <--- non-concise method
    return `${super.speak()}, Hola`
  }
};

Object.setPrototypeOf(multilinguist, englishPerson);

console.log(multilinguist.speak()); // -> Syntax Error

附加说明:

要使用一种不够简洁的方法实现上述操作,可以使用call()函数作为super的替代,示例如下:

const englishPerson = {
  speak() {
    return 'Hello';
  }
};

// Non-concise method utilizing `call` instead of `super`
const multilinguist = {
  speak: function() {
    return `${Object.getPrototypeOf(this).speak.call(this)}, Hola!`
  }
};

Object.setPrototypeOf(multilinguist, englishPerson);

console.log(multilinguist.speak()); // -> "Hello, Hola!"


请注意,方法与 super 关键字兼容的原因是因为它们被分配了一个内部的 [[HomeObject]] 属性(参见规范的 9.2.12 节)。[[HomeObject]] 属性对应于定义该方法的对象,可以用来获取该对象的原型。 - Oliver Sieweke
1
《理解ES6》一书中的更强大的原型一章,很好地展示了最后一个代码片段并不能完全替代super的例子。 - Oliver Sieweke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接