把符号带到ES6的动机是什么?

更新 :最近来自Mozilla的一篇精彩文章出现了。 如果你好奇,请阅读它。

正如你可能知道他们计划在ECMAScript 6中包含新的Symbol原始类型(更不用说其他一些疯狂的东西了)。 我一直认为Ruby中的:symbol概念是不必要的; 我们可以轻松地使用纯字符串,就像我们在JavaScript中所做的那样。 现在他们决定用JS来使JS复杂化。

我不明白这个动机。 有人可以向我解释我们是否真的需要JavaScript中的符号?


将符号引入Javascript的最初动机是启用私有属性。

不幸的是,他们最终被严重降级。 它们不再是私有的,因为您可以通过反射找到它们,例如,使用Object.getOwnPropertySymbols或代理。

他们现在被称为独特的符号,他们唯一的用途是避免名称冲突之间的属性。 例如,ECMAScript现在可以通过某些可以放在对象上的方法(例如定义它们的迭代协议)引入扩展挂钩,而不会冒着与用户名冲突的风险。

这是否足够强大,为语言添加符号的动机值得商榷。


符号不保证真正的隐私,但可以用来分隔物体的公共和内部属性。 让我们举一个例子,我们可以使用Symbol来拥有私有属性。

我们举一个例子,一个对象的属性不是私有的。

var Pet = (function() {
  function Pet(type) {
    this.type = type;
  }
  Pet.prototype.getType = function() {
    return this.type;
  }
  return Pet;
}());

var a = new Pet('dog');
console.log(a.getType());//Output: dog
a.type = null;
//Modified outside
console.log(a.getType());//Output: null

上面, Pet类属性type不是私有的。 为了保密,我们必须创建一个闭包。 下面的例子说明了我们如何使用闭包来实现私有type

var Pet = (function() {
  function Pet(type) {
    this.getType = function(){
      return type;
    };
  }
  return Pet;
}());

var b = new Pet('dog');
console.log(b.getType());//dog
b.type = null;
//Stays private
console.log(b.getType());//dog

上述方法的缺点:我们为每个创建的Pet实例引入一个额外的闭包,这会损害性能。

现在我们介绍一下Symbol 。 这可以帮助我们在不使用额外的不必要的关闭的情况下使财产变得私密 代码示例如下:

var Pet = (function() {
  var typeSymbol = Symbol('type');
  function Pet(type) {
    this[typeSymbol] = type;
  }
  Pet.prototype.getType = function(){
    return this[typeSymbol];
  }
  return Pet;
}());

var a = new Pet('dog');
console.log(a.getType());//Output: dog
a.type = null;
//Stays private
console.log(a.getType());//Output: dog

Symbols是一种新的特殊对象,可用作对象中的唯一属性名称。 使用Symbol而不是string s允许不同的模块创建不相互冲突的属性。 Symbols也可以是私有的,以便任何不能直接访问Symbol人都无法访问它们的属性。

Symbols是一个新的基元 。 就像numberstringboolean原语一样, Symbol有一个可用于创建它们的函数。 与其他基元不同, Symbols没有字面语法(例如, string s是如何产生'' ) - 创建它们的唯一方法是使用Symbol构造函数,方法如下:

let symbol = Symbol();

实际上, Symbol s只是将属性附加到对象上的一种稍微不同的方式 - 您可以轻松地将着名的Symbol s作为标准方法提供,就像Object.prototype.hasOwnProperty一样,它出现在从Object继承的所有内容中。

以下是Symbol基元类型的一些优点。

Symbols具有内置的可调试性

Symbols可以给出一个描述,这些描述实际上只是用于调试,以便在将它们记录到控制台时使生活更轻松。

Symbols可以用作Object

这是Symbol变得非常有趣的地方。 它们与物体严重交织在一起。 Symbol s可以指定为对象的关键字,这意味着您可以将无限数量的唯一Symbol分配给对象,并保证这些Symbol永远不会与string键或其他唯一Symbol冲突。

Symbols可以用作唯一值。

假设您有一个日志记录库,其中包含多个日志级别,例如logger.levels.DEBUGlogger.levels.INFOlogger.levels.WARN等。 在ES5代码中,您需要创建这些stringlogger.levels.DEBUG === 'debug' )或number s( logger.levels.DEBUG === 10 )。 这两个都不理想,因为这些值不是唯一的值,但Symbol是! 所以logger.levels简单地变成:

log.levels = {
  DEBUG: Symbol('debug'),
  INFO: Symbol('info'),
  WARN: Symbol('warn'),
};
log(log.levels.DEBUG, 'debug message');
log(log.levels.INFO, 'info message');

阅读这篇伟大的文章。

链接地址: http://www.djcxy.com/p/51707.html

上一篇: What is the motivation for bringing Symbols to ES6?

下一篇: Sound effects in JavaScript / HTML5