【ES6】Symbol

1.概述

你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。

let s = Symbol();
typeof s
let s1 =Symbol(‘foo‘)
s1 //Symbol(foo)
s1.toString() // ‘Symbol(foo)‘

如果 Symbol 的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个 Symbol 值。

const obj = {
      toString() {
          return "abc";
       }
};
const sym = Symbol(obj);
sym // Symbol(abc)

Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的

//没有参数的情况

let s1 = Symbol();

let s2 = Symbol();

s1 === s2 // false

// 有参数的情况

let s1 = Symbol(‘foo‘);

let s2 = Symbol(‘foo‘);

s1 === s2 // false

Symbol 值不能与其他类型的值进行运算,会报错。

let sym = Symbol(‘My symbol‘);

"your symbol is " + sym

// TypeError: can‘t convert symbol to string

Symbol 值可以显式转为字符串,也可以转为布尔值,但是不能转为数值。

let sym = Symbol(‘My symbol‘);

String(sym) // ‘Symbol(My symbol)‘

sym.toString() // ‘Symbol(My symbol)‘

let sym = Symbol();

Boolean(sym) // true

!sym  // false

Number(sym) // TypeError

sym + 2 // TypeError

2.Symbol.prototype.description

const sym=Symbol(‘foo‘)

sym.description //‘foo‘

3.作为属性名的Symbol

let mySymbol = Symbol();

let a = {};

a[mySymbol] = ‘Hello!‘;

let a = {

[mySymbol]: ‘Hello!‘

};

let a = {};

Object.defineProperty(a,mySymbol,{value:‘hello‘})

// 以上写法都得到同样结果

a[mySymbol] // "Hello!"

注意,Symbol 值作为对象属性名时,不能用点运算符。

const mySymbol = Symbol();

const a = {};

a.mySymbol = ‘Hello!‘;

a[mySymbol] // undefined

a[‘mySymbol‘] // "Hello!"

在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。

let s = Symbol();

let obj = {

[s](arg) { ... }

};

obj[s](123);

4.实例:消除魔术字符串

const shapeType = {

triangle: ‘Triangle‘

};

function getArea(shape, options) {

let area = 0;

switch (shape) {

case shapeType.triangle:

area = .5 * options.width * options.height;

break;

}

return area;

}

getArea(shapeType.triangle, { width: 100, height: 100 });

const shapeType = {

triangle: Symbol()

};

5.属性名的遍历

Symbol作为属性名改属性不会出现在for...in、for...of中

也不会Object.keys、Object.getOwnPropertyNames()、JSON.stringify()返回

可以通过Object.getOwnPropertySymbols(),获取所有Symbol属性名

Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

let obj = {

[Symbol(‘my_key‘)]: 1,

enum: 2,

nonEnum: 3

};

Reflect.ownKeys(obj)

//  ["enum", "nonEnum", Symbol(my_key)]

6.Symbol.for()

重新使用同一个 Symbol 值,Symbol.for方法可以做到这一点。

它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。

如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。

let s1 = Symbol.for(‘foo‘);

let s2 = Symbol.for(‘foo‘);

s1 === s2

Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。

let s1 = Symbol.for("foo");

Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");

Symbol.keyFor(s2) // undefined

Symbol.for为 Symbol 值登记的名字

原文地址:https://www.cnblogs.com/Mijiujs/p/12113453.html

时间: 2024-09-29 06:18:18

【ES6】Symbol的相关文章

【ES6】更易于继承的类语法

和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态.派生.抽象.迭代.单例等,而且根据 ES6 的新特性衍生出很多有趣的用法. 一.类的基本定义 基本所有面向对象的语言都支持类的封装与继承,那什么是类? 类是面向对象程序设计的基础,包含数据封装.数据操作以及传递消息的函数.类的实例称为对象. ES5 之前通过函数来模拟类的实现如下: // 构造函数 function Person(name) { this.name = name; } //

【ES6】---JavaScript(一)

一.新增数据类型Symbol 概念: Symbol代表独一无二的 Symbol类型的值通过Symbol函数来生成,同时Symbol函数返回的值是唯一的 Symbol函数可以接收字符串作为参数,但是即使相同参数返回的值也是唯一的 作用: 属性私有化 数据保护 没有参数的情况 var s1 = Symbol(); var s2 = Symbol(); s1 === s2 // false 有参数的情况 var s1 = Symbol("foo"); var s2 = Symbol(&quo

【ES6】---JavaScript(二)

一.数组中新增的方法     1.Array.of() // Array.of():函数作用:将一组值,转换成数组 var arr = Array.of(1,2,3,4); console.log(arr);// [1,2,3,4]  2.Array from函数 // Array.from:将伪数组转换为数组 var aLi = Array.from(document.getElementsTagName("li")); console.log(aLi instanceof Arra

【ES6】对象的扩展

Object.setPrototypeOf(obj, proto) Object.getPrototypeOf(obj) Object.getOwnPropertyDescriptor(obj,property) 获取该属性的描述对象.描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,下列操作会忽略当前属性 for...in循环:只遍历对象自身的和继承的可枚举的属性. Object.keys():返回对象自身的所有可枚举的属性的键名. JSON.stringify()

【ES6】async

async就是Generator函数的语法糖 将 Generator 函数的星号(*)替换成async,将yield替换成await const gen = function* () { const f1 = yield readFile('/etc/fstab'); const f2 = yield readFile('/etc/shells'); console.log(f1.toString()); console.log(f2.toString()); }; const asyncRea

【es6】js原生的promise

JavaScript 是单线程的,这意味着任何两句代码都不能同时运行,它们得一个接一个来.在浏览器中,JavaScript 和其他任务共享一个线程,不同的浏览器略有差异,但大体上这些和 JavaScript 共享线程的任务包括重绘.更新样式.用户交互等,所有这些任务操作都会阻塞其他任务. 一.事件的不足 对于那些执行时间很长,并且长时间占用线程的代码,我们通常使用异步来执行,但是又如何判断其是否执行完毕或者失败呢?我们通常使用事件监听,但事件监听只能监听绑定之后发生的事件,但有可能你写绑定事件代

【ES6】最常用的es6特性(二)

1.for of 值遍历 for in 循环用于遍历数组,类数组或对象,ES6中新引入的for of循环功能相似,不同的是每次循环它提供的不是序号而是值. var someArray = [ "a", "b", "c" ]; for (v of someArray) { console.log(v);//输出 a,b,c } 2.iterator, generator基本概念 2.1 iterator:它是这么一个对象,拥有一个next方法,这个

【ES6】最常用的es6特性(一)

参考链接: http://www.jianshu.com/p/ebfeb687eb70 http://www.cnblogs.com/Wayou/p/es6_new_features.html 1.let, const 这两个的用途与var类似,都是用来声明变量的,但在实际运用中他俩都有各自的特殊用途. 1.1第一种场景就是你现在看到的内层变量覆盖外层变量 var name = 'zach' while (true) { var name = 'obama' console.log(name)

【ES6】includes(), startsWith(), endsWith()

includes():返回布尔值,表示是否找到了参数字符串. startsWith():返回布尔值,表示参数字符串是否在原字符串的头部. endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部. 支持第二个参数,表示开始搜索的位置. 原链接:http://es6.ruanyifeng.com/#docs/string#includes-startsWith-endsWith