ES6

栏目: JavaScript · 发布时间: 5年前

内容简介:ES6引进了一种新的原始数据类型Symbol表示独一无二的值。它是JavaScript语言的第七种类型。Symbol值是通过Symbol函数生成。这就是说,对象的属性名吸纳在可以有两种类型,一种是原来的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名冲突。注意:

Symbol

概述

ES6引进了一种新的原始数据类型Symbol表示独一无二的值。它是JavaScript语言的第七种类型。

Symbol值是通过Symbol函数生成。这就是说,对象的属性名吸纳在可以有两种类型,一种是原来的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名冲突。

let s = Symbol();
alert(typeof s)  //Symbol

注意:

1.symbol函数不能使用new命令,否则会报错
2.Symnol是一个原始类型的值,不是对象(不能添加属性)
3.它是一种类似于字符串的数据类型

Symbol函数可以接收一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时比较容易区分。

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

// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();
s1 === s2 // false

//有参数的情况
let s1 = Symbol('foo')
let s1 = Symbol('bar')
s1 === s2 // false 
  
//如果参数是一个对象,就会调用改对象的toString方法,将其转为字符串,然后才生成一个Symbol值
const obj = {
    toString() {
        return 'abc';
    }
};
const sym = Symbol(obj);
sym // Symbol(abc)

作为属性名的Symbol

let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
a.mySymbol  // undefined  //作为对象属性名时,不能用点运算符。

a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
//因为点运算符后面是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个 Symbol 值。

属性名的遍历

Symbol作为属性名,该属性不会出现在for...in、for...of也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()

返回。但是它也不是私有属性。有一个Object。getOwnPropertySymbols方法,可以获取指定对象的所有Symbol属性名。

Object.getOwnPropertySymbol方法返回的是一个数组,成员是当前对象中所有用作属性名的Symbol值。

const obj = {};

let foo = Symbol("foo");

Object.defineProperty(obj, foo, {
  value: "foobar",
});

for (let i in obj) {
  console.log(i); // 无输出
}

Object.getOwnPropertyNames(obj)
// []

Object.getOwnPropertySymbols(obj)
// [Symbol(foo)]

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

let obj = {
  [Symbol('my_key')]: 1,
  enum: 2,
  nonEnum: 3
};

Reflect.ownKeys(obj)
//  ["enum", "nonEnum", Symbol(my_key)]

由于以Symbol值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的,但又希望只用于内部的方法。

let size = Symbol('size');
class Collection{
    constructor(){
        this[size] = 0;
    }
}
add(item){
    this[this[size]] = item;
    this[size]++;
}
static sizeOf(instance){
    return instance[size];
}

let x = new Collection();
Collection.sizeOf(x); //0

x.add('foo');
Collection.sizeOf(x) // 1

Object.keys(x) // ['0']
Object.getOwnPropertyNames(x) // ['0']
Object.getOwnPropertySymbols(x) // [Symbol(size)]
//对象x的size属性是一个Symbol值,所有Object.key(x)、object.getOwnPropertyName(x)

symbol.for(),symbol.keyFor()

有时,我们希望重新使用同一个Symbol值,symbol.for()方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2  //true

Symbol.for()与Symbol()这两种写法,都会生成新的Symbol,它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的Symbol类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。

Symbol.for("bar") === Symbol.for("bar")
// true

Symbol("bar") === Symbol("bar")
// false

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

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

let 上 = Symbol("foo");
Symbol.keyFor(s2);  //undefined

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ruby on Rails Tutorial

Ruby on Rails Tutorial

Michael Hartl / Addison-Wesley Professional / 2012-8-6 / USD 44.99

"Ruby on Rails(TM) Tutorial by Michael Hartl has become a must-read for developers learning how to build Rails apps." -Peter Cooper, Editor of Ruby Inside Using Rails, developers can build web applica......一起来看看 《Ruby on Rails Tutorial》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具