前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解ES6--Set、Map及Symbol

深入理解ES6--Set、Map及Symbol

作者头像
奋飛
发布2019-08-14 18:04:47
3740
发布2019-08-14 18:04:47
举报
文章被收录于专栏:Super 前端Super 前端

Set集合和Map集合

Set集合是一种无重复元素的列表,通常用来检测给定的值在某个集合中是否存在;Map集合内含多组键值对,通常用来缓存频繁取用的数据。

ES5中的问题

代码语言:javascript
复制
var map = Object.create(null)
map[5] = 'foo'
console.log(map[5], map['5']) // 'foo' 'foo'

let key1 = {}
let key2 = {}
map[key1] = 'bar'
console.log(map[key2]) // 'bar'

由于对象属性名必须是字符串,所以5会转换为字符串”5”;而key1和key2会转换为["object Object"]对于,Set集合和Map集合是严格区分的,通过Object.is()判断实现

Set去重

代码语言:javascript
复制
let ary = [1, 2, 3, 2, 3]
let distAry = [...new Set(ary)] // [1, 2, 3]

forEach函数

代码语言:javascript
复制
myAry.forEach(callback(currentValue, index, array){}, this)
mySet.forEach(callback(value1, value2, set){}, this)
myMap.forEach(callback(value, key, Map){}, thisArg])

Symbol

Symbol 是继字符串、数值、布尔值、null、undefined后的第6中原始类型,但和其原始类型不同的是,Symbol没有字面量形式。

Symbol共享体系

有时希望在不同代码中共享一个Symbol,ES6中提供了一个可随时访问的全局Symbol注册表,可通过Symbol.for()创建共享的Symbol。

代码语言:javascript
复制
let name = Symbol.for('name')
let p = {
    [name]: 'ligang'
}
let otherName = Symbol.for('name')
console.log(name === otherName) // true
console.log(p[otherName]) // 'ligang'

属性检索

代码语言:javascript
复制
let name = Symbol.for('name')
let p = {
    [name]: 'ligang',
    age: 28
}
Object.defineProperty(p, 'age', {enumerable: false})

console.log(Object.keys(p)) // []
console.log(Object.getOwnPropertyNames(p)) // ["age"]
console.log(Object.getOwnPropertySymbols(p)) // [Symbol(name)]
  • Object.keys():返回一个由一个给定对象的自身可枚举属性组成的数组; 与 for-in主要区别是,or-in 循环还会枚举其原型链上的属性
  • Object.getOwnPropertyNames():返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组;
  • Object.getOwnPropertySymbols():返回一个给定对象自身的所有 Symbol 属性的数组

通过well-known Symbol暴露内部操作

ES6通过在原型链上定义与Symbol相关的属性来暴露更多的语言内部逻辑。

  • Symbol.hasInstance用于判断某对象是否为某构造器的实例;可以用它自定义instanceof操作符在某个类上的行为 ;
  • Symbol.isConcatSpreadable:用于配置某对象作为Array.prototype.concat()方法的参数时是否展开其数组元素;
  • Symbol.match:指定了匹配的是正则表达式而不是字符串;String.prototype.match()方法会调用此函数;
  • Symbol.iterator:为每一个对象定义了默认的迭代器;该迭代器可以被 for...of 循环使用;
  • Symbol.replace :指定了当一个字符串替换所匹配字符串时所调用的方法。String.prototype.replace()方法会调用此方法;
  • Symbol.search:定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标,这个方法由以下的方法来调用 String.prototype.search() ;
  • Symbol.species:是个函数值属性,其被构造函数用以创建派生对象;
  • Symbol.split:指向 一个正则表达式的索引处分割字符串的方法。 这个方法通过 String.prototype.split() 调用;
  • Symbol.toPrimitive:将被调用的指定函数值的属性转换为相对应的原始值;
  • Symbol.toStringTag:一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。
Symbol .hasInstance
代码语言:javascript
复制
let Person = function(name) {this.name = name}
let p = new Person('ligang')
console.log(p instanceof Person) // true
console.log(Person[Symbol.hasInstance](p)) // true

// 修改Symbol .hasInstance行为
Object.defineProperty(Person, Symbol.hasInstance, {
    value: function(v) {
        return false
    }
})
let p2 = new Person('ligang')
console.log(p2 instanceof Person) // false
console.log(Person[Symbol.hasInstance](p2)) // false
Symbol.toPrimitive

在一些操作时,我们会经常讲对象转换为相应的原始值(如,+,==)。Symbol.toPrimitive方法被定义在每一个标准类型的原型上,并且规定了当对象转换为原始值时应当执行的操作。Symbol.toPrimitive会接收类型提示参数(“number”、“string”和“default”之一)。

对于大多数标准对象,数字模式优先级如下:

  1. 调用valueOf()方法,如果结果为原始值,则返回;
  2. 否则,调用toString()方法,如果结果为原始值,则返回;
  3. 如果再无可选值,抛出错误。

对于大多数标准对象,字符串模式优先级如下:

  1. 调用toString()方法,如果结果为原始值,则返回;
  2. 否则,调用valueOf()方法,如果结果为原始值,则返回;
  3. 如果再无可选值,抛出错误。
代码语言:javascript
复制
// 没有 Symbol.toPrimitive 属性的对象
var obj1 = {};
console.log(+obj1);     // NaN
console.log(`${obj1}`); // "[object Object]"
console.log(obj1 + ""); // "[object Object]"

// 拥有 Symbol.toPrimitive 属性的对象
var obj2 = {
  [Symbol.toPrimitive](hint) {
    if (hint == "number") {
      return 10;
    }
    if (hint == "string") {
      return "hello";
    }
    return true;
  }
};
console.log(+obj2);     // 10      -- hint is "number"
console.log(`${obj2}`); // "hello" -- hint is "string"
console.log(obj2 + ""); // "true"  -- hint is "default"
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年04月04日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Set集合和Map集合
    • ES5中的问题
      • Set去重
        • forEach函数
        • Symbol
          • Symbol共享体系
            • 属性检索
              • 通过well-known Symbol暴露内部操作
                • Symbol .hasInstance
                • Symbol.toPrimitive
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档