Symbol 数据类型在 ES6 中起什么作用?

转载自:https://www.jianshu.com/p/425148370333?utm_source=oschina-app

一、概述

在ES5中,对象属性名都是字符串容易造成属性名冲突。为了避免这种情况的发生,ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。
symbol 是JavaScript 在ES6 中一种基本数据类型。Symbol() 函数返回的是 Symbol 类型的值,该类型具有静态方法和静态属性。

1、定义

Symbol([description])
参数 description 是一个可选参数,是一个字符串,可以用于调试,但不能访问Symbol 自身。

var sym1 = Symbol();
var sym2 = Symbol('foo');
var sym3 = Symbol('foo');
2、每一个 Symbol() 返回的值都是唯一的。一个Symbol 值能作为对象属性的标识符,这是改数据类型仅有的目的。
Symbol("yuan") === Symbol("yuan"); // false 
3、不可以使用 new 操作符
var sym = new Symbol(); // TypeError报错
4、结合 Object() 函数,创建一个 Symbol 包装器对象
var sym = Symbol();
typeof sym;  // "symbol“”
var symobj = Object(sym);
typeof symobj; // "object"
5、全局共享 Symbol

上面使用 Symbol() 函数的语法,不会在你的整个代码库中创建一个可用的全局 symbol类型。要创建跨文件可用的symbol,甚至跨域(每个都有它自己的全局作用域) , 使用Symbol.for() 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中从全局的symbol注册?表设置和取得symbol。

6、在对象中查找 Symbol 属性
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols)         // [Symbol(a), Symbol(b)]

二、静态属性

1、length 属性
Symbol.length // 0

Symbol 的长度属性值为0.

2、迭代 Symbols

Symbol.iterator
该方法为每一个对象定义了默认的迭代器。该迭代器可以被 for.. of 循环使用。
自定义迭代器

var myIterator = {};
myIterator[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterator] // [1, 2, 3]

Symbols 与 for... in 迭代

var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";

for (var i in obj) {
   console.log(i); 
}
// "c"
// "d"
3、Symbol的正则表达式:用于标识对象是否具有正则表达式的行为

Symbol.match:对象是否具有指定的匹配的正则表达式

"/bar/".startsWith(/bar/); 
// Throws TypeError, 因为 /bar/ 是一个正则表达式
// 且 Symbol.match 没有修改。

如果你将 Symbol.match 置为 false,使用 match 属性的表达式检查会认为该象不是正则表达式对象。startsWith 和 endsWith 方法将不会抛出 TypeError。

var re = /foo/;
re[Symbol.match] = false;
"/foo/".startsWith(re); // true
"/baz/".endsWith(re);   // false

Symbol.replace
这个属性指定了当一个字符串替换所匹配字符串时所调用的方法。String.prototype.replace() 方法会调用此方法。
Symbol.search
指定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标,这个方法由以下的方法来调用 String.prototype.search()。
Symbol.split
指向 一个正则表达式的索引处分割字符串的方法。 这个方法通过 String.prototype.split() 调用。

4、其他属性

Symbol.hasInstance
一个确定一个构造器对象识别的对象是否为它的实例的方法。使用 instanceof.
Symbol.isConcatSpreadable
一个布尔值,表明一个对象是否应该flattened为它的数组元素。使用Array.prototype.concat().
Symbol.unscopables
拥有和继承属性名的一个对象的值被排除在与环境绑定的相关对象外。
Symbol.species
一个用于创建派生对象的构造器函数。
Symbol.toPrimitive
一个将对象转化为基本数据类型的方法。
Symbol.toStringTag
用于对象的默认描述的字符串值。使用Object.prototype.toString().

三、静态方法

1、Symbol.for(key)

改方法根据给定的键 key, 从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表。
这里的参数key,是一个字符串,作为 symbol 注册表中与某 symbol 关联的键。
和 Symbol() 不同的是,用Symbol.for() 方法创建的 symbol 会被放入一个全局 symbol 注册表中。Symbol.fo() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了,如果是,则会直接返回上次存储的那个。否则,会再新建一个。

Symbol.for("foo"); // 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"
Symbol.for("foo"); // 从 symbol 注册表中读取键为"foo"的 symbol

Symbol.for("bar") === Symbol.for("bar"); // true,证明了上面说的
Symbol("bar") === Symbol("bar"); // false,Symbol() 函数每次都会返回新的一个 symbol

var sym = Symbol.for("mario");
sym.toString(); 
// "Symbol(mario)",mario 既是该 symbol 在 symbol 注册表中的键名,又是该 symbol 自身的描述字符串
2、Symbol.keyFor(sym)

该方法用来获取 symbol 注册表中与某个 symbol 关联的键。
参数 sym 是指存储在 symbol 注册表中的某个 symbol。

// 创建一个 symbol 并放入 Symbol 注册表,key 为 "foo"
var globalSym = Symbol.for("foo"); 
Symbol.keyFor(globalSym); // "foo"

// 创建一个 symbol,但不放入 symbol 注册表中
var localSym = Symbol(); 
Symbol.keyFor(localSym); // undefined,所以是找不到 key 的

本章介绍了JavaScript 的一个新的基础数据类型:Symbol,需要掌握此类型数据在JavaScript 所充当的具体角色,以及其属性的具体含义,和Symbol两个方法的应该用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 一、概述在ES5中,对象属性名都是字符串容易造成属性名冲突。为了避免这种情况的发生,ES6引入了一种新的原始数据类...
    贵在随心阅读 14,558评论 0 8
  • 1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象...
    赵然228阅读 798评论 2 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 09年加入豆瓣,到现在已经有将近八年了。今天翻看自己的广播,越看越是伤感,为了自己,为了时间。 在豆瓣上关注的第一...
    ___之阅读 246评论 0 0
  • 早上去了公司,中午约了一个朋友一起吃饭和帮忙做了一下聆听,感觉对方可能是心中心的3号(补充:九型人格有分三个中心:...
    岚妈成长历程阅读 471评论 0 1