专栏首页前端儿ES6笔记(4)-- Symbol类型

ES6笔记(4)-- Symbol类型

  系列文章 -- ES6笔记系列

Symbol是什么?中文意思是标志、记号,顾名思义,它可以用了做记号。 是的,它是一种标记的方法,被ES6引入作为一种新的数据类型,表示独一无二的值。 由此,JS的数据类型多了一位成员: Number、String、Boolean、undefined、Object、Symbol

一、简单使用

1. 声明

类似字符串String的声明方式 var str = 'str'; Symbol的声明方式类似,它调用构造函数Symbol()

var s = Symbol();
typeof s // symbol

2. 使用

Symbol声明了是为了使用

var s = Symbol();
var s1 = Symbol();

console.log(s, s1);
console.log(s == s1); // false

Chrome的输出中自动对Symbol类型的数据做了标识处理,由输出知道,虽然通过Symbol生成的两个标志不相同,但两个变量混淆了分不清。

实际上,为了区别出不同的symbol,我们可以在参数中指定

var s = Symbol('s');
var s1 = Symbol('s1');

console.log(s, s1);

symbol除了简单的在控制台输出之外,还可以参与到其他代码逻辑运算中去,最常见的是在对象属性名称中(为确保属性名惟一而存在)

var s = Symbol();
var s1 = Symbol('s1');

var obj = {
    [s]: function() {
        console.log(1);
    },
    [Symbol()]: () => {
        console.log(2);
    },
    [s1]: 3
};

obj[s]() // 1
obj[s1] // 3

注意到symbol要使用[]中括号包裹起来,调用的时候也一样(不能使用obj.s的方式,这样会被识别成字符串)

3. 属性的遍历

如上代码,如果我们想遍历对象的属性值,也许会这样操作

for (var item in obj) {
    if (typeof obj[item] === 'function') {
        obj[item]();
    } else {
        console.log(obj[item]);
    }
}

Object.keys(obj).forEach(function(item) {
    if (typeof obj[item] === 'function') {
        obj[item]();
    } else {
        console.log(obj[item]);
    }
});

却发现什么也没输出

因为要获取到Symbol这个属性名,ES6引入了新的方法,旧的for...in  Object.keys()、Object.getOwnPropertyNames()等不支持访问

使用新的getOwnPropertySymbols方法

var s = Symbol();
var s1 = Symbol('s1');

var obj = {
    [s]: function() {
        console.log(1);
    },
    [Symbol()]: () => {
        console.log(2);
    },
    [s1]: 3,
    a: 4
};



Object.getOwnPropertySymbols(obj).forEach(function(item) {
    if (typeof obj[item] === 'function') {
        obj[item]();
    } else {
        console.log(obj[item]);
    }
});

// 输出 1 2 3

虽然识别了symbol类属性,但常规属性却被忽略了,所以ES6还引入了一个新的内置类Reflect,它的ownKeys方法可以识别出所有属性名

var s = Symbol();
var s1 = Symbol('s1');

var obj = {
    [s]: function() {
        console.log(1);
    },
    [Symbol()]: () => {
        console.log(2);
    },
    [s1]: 3,
    a: 4
};



Reflect.ownKeys(obj).forEach(function(item) {
    if (typeof obj[item] === 'function') {
        obj[item]();
    } else {
        console.log(obj[item]);
    }
});

// 输出 4 1 2 3

4. 类型转换

数字转换成字符串我们可以简单的使用 + '' 实现,symbol呢

var s = Symbol();
var s1 = Symbol('s1');

s + '' // Uncaught TypeError: Cannot convert a Symbol value to a string

出错了,提示不能转换。

实际上,我们只是不能直接转换值,还是可以用toString或String方法转换这个标志的

var s = Symbol();
var s1 = Symbol('s1');

s.toString() // Symbol()
String(s1) // Symbol(s1)

类似的,也可以转换为bool值

var s = Symbol();
var s1 = Symbol('s1');

!!s // true
!s // false
Boolean(s1) // true

不过,symbol是不能转换成数值Number类型的

5. Symbol.for()相同值的使用

有时候我们需要使用同一个symbol值,而调用Symbol()的时候会自动创建不同的值

var temp = [];

var scores = [{
    name: 'jack',
    score: 10
}, {
    name: 'pick',
    score: 20
}, {
    name: 'pick',
    score: 30
}];

scores.forEach(function(item) {
    
    temp.push({
        name: Symbol(item.name),
        score: item.score
    });
});

temp[1].name == temp[2].name // false

以上代码主要为了登记不同用户的分数,并确保唯一性使用了symbol,但最终用户名都为pick的项不想等,可能会导致后续的计算出错

把Symbol换成Symbol.for,输出才为true

两者类似,都可以生成一个Symbol类型的值,但后者是先判断全局中是否有该symbol值,有就返回该值,没有才创建,并将该值登记在全局中

var s = Symbol.for('s');
var s1 = Symbol.for('s');

s == s1 // true
s === s1 // true

var s = Symbol('s');
var s1 = Symbol('s');

s == s1 // false
s === s1 // false

此外,我们可以用Symbol.keyFor()访问全局中的symbol相关项,没有则返回undefined

var s = Symbol.for('s');
var s1 = Symbol.for('s');

Symbol.keyFor(s) // s
Symbol.keyFor(s1) // s
Symbol.keyFor(s2) // Uncaught ReferenceError: s2 is not defined


var s3 = Symbol('s3');
Symbol.keyFor(s3) // undefined

6. Symbol的更多使用

Symbol的更多使用方法,可参考 MDN - Symbol

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端代码相关规范

    项目目录和文件的命名使用小写字母,避免使用大写或驼峰,多个单词以下划线 _ 分隔  如:my_project/cast_detail.js

    书童小二
  • 前端读取Excel报表文件

    在实际开发中,经常会遇到导入Excel文件的需求,有的产品人想法更多,想要在前端直接判断文件内容格式是否正确,必填项是否已填写

    书童小二
  • ES6笔记(3)-- 解构赋值

    其实,解构赋值内部的实现方式使用到了ES6的Iterator迭代器,通过层层遍历,保证了相应值的获取

    书童小二
  • 应用潜在语义分析技术将文档进行3D可视化

    这里使用了 WPF(译者注:Windows Presentation Foundation) 的 3D 展示功能来对一个文档集合进行了可视化,这些文...

    StoneDemo
  • 从源码角度看 PHP 字符串类型转换

    PHP 的类型转换是比较方便的,但是越是容易使用的东西,底层的实现越是复杂,而且在使用中像我这样的新手也往往不清楚转换后的结果到底是什么。有时候...

    码农UP2U
  • 全民刷军装背后的AI技术及简单实现

    昨天有Design-AI-Lab用户后台留言,问为什么换军装的h5这么火,但没见到有技术文章分析如何实现。 我回复说,大概是比较简单吧,主要工作是图像合成。 ...

    mixlab
  • Javascript[0x06] -- 基于Javascript范畴代码风格和规范的总结

    抓重点: 这么多要看到猴年马月去,找一个对的上眼的深入学习下,切勿都学,没这个必要,粗略扫读,有针对性阅读!

    丰臣正一
  • js笔记

    1.克隆对象 克隆数组: var country=['中国','美国']; var copyCountry=country.slice(0); 克隆对象: va...

    用户1055830
  • 微信 支付宝 支付技术 源码介绍

    最近,公司因为智慧消防项目推出智能充电桩的项目,马上要进行充电桩设备管理系统的研发,拟使用微信二维码来实现这个收款,所以整理了一下微信支付和支付宝支付技术。

    闫小林
  • Github标星5300+,专门为程序员开发文档开源管理系统

    目前,它已经在Github上标星超5300,1.3K个Fork,Github地址:

    加米谷大数据

扫码关注云+社区

领取腾讯云代金券