Last Surprise Lyn
  1. 1 Last Surprise Lyn
  2. 2 One Last You Jen Bird
  3. 3 Hypocrite Nush
  4. 4 Time Bomb Veela
  5. 5 The Night We Stood Lyn
  6. 6 Quiet Storm Lyn
  7. 7 Flower Of Life 发热巫女
  8. 8 Libertus Chen-U
  9. 9 かかってこいよ NakamuraEmi
  10. 10 Warcry mpi
  11. 11 Life Will Change Lyn
2017-03-05 12:22:36

新的基本数据类型——符号(Symbol)

在符号诞生之前,我们的对象属性名都是字符串,这不仅容易造成属性名的冲突,而且属性可以被轻易的更改。所以我们需要一种'私有名称'来创建非字符串类型的属性名来防止常规的更改。这就是JS已有的基本类型(字符串,数值,布尔,null,undefined)之外,新增基本类型(Symbol)的目的之一。


普通符号的创建

符号没有字面量形式,只可以使用Symbol()全局函数创建。例子如下:

let ex = Symbol('desc'),
    a = {};
a[ex] = 'val';
console.log(ex); // Symbol(desc)
console.log(typeof ex); // symbol

Symbol()接受一个字符串参数,表示对生成符号的描述,描述信息存储在内部属性[[Description]]中,一般用于调试,只能通过String()方法读取。不同的符号可以使用相同的描述,但是符号值是不相等的,每个符号都是唯一的。可以通过typeof运算符来判断一个变量是否为符号。


共享符号的创建

由于我们创建的每个符号都是唯一的,换句话说,如果我们想在不同的代码段中使用相同的符号标识取到同一个属性,我们就必须到原始创建的代码中取到这个标识。跨代码追踪无疑是很麻烦的,为此,我们可以使用Symbol.for()方法创建一个全局共享符号。例子如下:

let a = Symbol.for('one');
let b =Symbol.for('one');
console.log(a === b); // true
console.log(Symbol.keyFor(a, b)) // one one 

Symbol.for()方法接受单个字符串为描述键值参数,创建的符号都存放在全局符号注册表里。首先会根据该参数搜索全局符号表,看看是否存在参数相同的符号,若存在则返回该值,若不存在则新建。   可以使用Symbol.keyFor()方法根据符号值检索出对应的描述键值。


符号的使用

由于符号的唯一性,将符号作为对象的属性名是最常用的方式,可以防止某个属性被改写或覆盖。写法如下:

let sym = Symbol();
// 方法一
let a = {};
a[sym] = 'val';
// 方法二
let a = {
  [sym]: 'val';
}
// 方法三
let a = {};
Object.defineProperty(a, sym, {value: 'val'});

注意将Symbol作为对象属性名时不能用点运算符,因为点运算符后读取的值为字符串。 除了当作唯一的属性名之外,我们在需要唯一的值作判定时,也可以用Symbol来代替字符串。最典型的应用就是switch语句了。对每一个case,我们都可以使用symbol值保证按照期待的值工作。


符号的类型转换和检索方法

虽然符号属于基本类型的一种,但由于它的独特唯一性,一般都很难进行转换。只能通过显式的String()方法输出,toString()方法会引发错误。console.log有效则是调用了String()。还可以通过Boolean()方法转化为布尔值,但不可以通过Number()转化为数值。 检索对象属性时,我们一般采用Object.keys()或Object.getOwnPropertyNames()。前者返回所有可枚举属性名称,后者返回所有属性名称。但两者都不能返回符号属性。ES6新增了Object.getOwnPropertySymbols()方法,该方法返回一个数组,包含了对象自有的符号值,但不包含从原型上继承的符号值。


知名符号

ES6在全局Symbol对象中定义了一些属性,这些属性统称为知名符号,目前共有11个,这些属性对原先属于语言内部逻辑的一些部分进行了接口暴露,允许用户来定义这些基础行为,增强了JS的灵活性。由于不同知名符号的用法涉及JS的各个部分,以下仅作概述,具体使用方法将分别整合在今后相关模块的文章中。

  • Symbol.hasInstance: 该方法定义在Funcition.prototype上,用来检测值是否为函数的一个实例。使用instanceof操作符时调用。
  • Symbol.isConcatSpreadable: 一个布尔值,在集合对象作为参数传递给Array.prototype.concat()方法时,表示该对象是否可以展开。
  • Symbol.iterator: 返回迭代器。
  • Symbol.species: 用于产生派生对象的构造器。
  • Symbol.unscopables: 一个对象,指定了哪些属性名不允许被包含在with语句中。
  • Symbol.toPrimitive: 隐式类型转换时,定义转换规则。
  • Symbol.match:定义String.prototype.match()的规则。用于比较字符串。
  • Symbol.replace:定义String.prototype.replace()的规则。用于替换字符串。
  • Symbol.search:定义String.prototype.search()的规则。用于定位字符串。
  • Symbol.split: 定义String.prototype.split()的规则。用于分割字符串。
  • Symbol.toStringTag: 定义String.prototype.toString()的规则。用于创建描述信息。

-- EOF --

添加在分类「 前端开发 」下,并被添加 「JavaScript」 标签。

文章目录

 - [普通符号的创建](#普通符号的创建)
 - [共享符号的创建](#共享符号的创建)
 - [符号的使用](#符号的使用)
 - [符号的类型转换和检索方法](#符号的类型转换和检索方法)
 - [知名符号](#知名符号)
回到首页