ES6之原始数据类型Symbol

简介: ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。

引言

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。

概述

symbol 是一种基本数据类型。Symbol() 函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。

Symbol的原理是通过调用Symbol函数来创建一个新的Symbol值。每个通过Symbol函数创建的值都是唯一且不可变的。

基本用法

1. 创建一个唯一的属性键

constsym=Symbol();
constobj= {
   [sym]: 'value'};
console.log(obj[sym]); // value

2. 使用描述符创建一个带有描述信息的Symbol值

constsym=Symbol('description');
console.log(sym); // Symbol(description)

3. 使用全局注册表共享Symbol值

constsym1=Symbol.for('key');
constsym2=Symbol.for('key');
console.log(sym1===sym2); // true

4. 获取已注册的全局Symbol键

constkey=Symbol.keyFor(sym1);
console.log(key); // key

5. 遍历对象中所有使用了Symbol作为键名的属性

constsym=Symbol();
constobj= {
   [sym]: 'value',
foo: 'bar'};
for (letkeyinobj) {
console.log(key); // foo,不会输出sym}

6. 使用内置的Well-known Symbols来自定义对象行为

classMyObject {
   [Symbol.toStringTag]() {
return'MyObject';
   }
}
constobj=newMyObject();
console.log(obj.toString()); // [object MyObject]

7. 使用Symbol来定义类的私有属性

const_privateProperty=Symbol('private');
classMyClass {
constructor() {
this[_privateProperty] ='private value';
  }
getPrivateProperty() {
returnthis[_privateProperty];
  }
}
constmyObj=newMyClass();
console.log(myObj.getPrivateProperty()); // private valueconsole.log(myObj[_privateProperty]); // undefined

这些示例展示了Symbol的一些基本用法,包括创建唯一的属性键、使用描述符创建Symbol值、使用全局注册表共享Symbol值、遍历对象属性、使用Well-known Symbols自定义对象行为以及定义类的私有属性等。这些用法可以帮助我们更好地理解和应用Symbol。

Symbol属性

当使用内置的Symbol属性时,JavaScript引擎会根据这些属性的特定用途来执行相应的操作。下面是对每个示例的用法原理进行解释:

1. Symbol.iterator

  • 当使用for...of循环遍历一个对象时,JavaScript引擎会查找该对象是否有一个Symbol.iterator方法。
  • 如果存在Symbol.iterator方法,它应该返回一个迭代器对象,该迭代器对象包含next方法。
  • 在每次迭代中,for...of循环会调用迭代器对象的next方法,并将返回的值赋给循环变量。
constobj= {
data: ['a', 'b', 'c'],
  [Symbol.iterator]() {
letindex=0return {
next: () => {
if (index<this.data.length) {
return { value: this.data[index++], done: false }
        } else {
return { done: true }
        }
      }
    }
  }
}
for (letitemofobj) {
console.log(item) // a, b, c}

2. Symbol.toStringTag

  • 当调用对象的toString()方法时,JavaScript引擎会检查该对象是否有一个Symbol.toStringTag属性。
  • 如果存在Symbol.toStringTag属性,它应该是一个字符串值,表示自定义的字符串标签。
  • JavaScript引擎将使用这个标签来构造toString()方法返回的字符串。
constobj= {
  [Symbol.toStringTag]: 'MyObject',
};
console.log(obj.toString()); // [object MyObject]

3. Symbol.hasInstance:

  • 当使用instanceof操作符检查一个实例是否属于某个类时,JavaScript引擎会查找这个类是否有一个静态方法[Symbol.hasInstance]。
  • 如果存在[Symbol.hasInstance]方法,它应该接受一个参数,并返回一个布尔值表示实例是否属于这个类。
classMyClass {
static [Symbol.hasInstance](instance) {
returnArray.isArray(instance)
    }
}
console.log([] instanceofMyClass) // trueconsole.log({} instanceofMyClass) // false

4. Symbol.species:

  • 当在派生类中调用Array原型上的方法(如map、filter等)创建新实例时,JavaScript引擎会查找派生类是否有一个静态属性[Symbol.species]。
  • 如果存在[Symbol.species]属性,它应该是一个构造函数,用于创建新实例。
  • JavaScript引擎将使用[Symbol.species]指定的构造函数来创建新实例,而不是使用派生类本身的构造函数。
classMyArrayextendsArray {
staticget [Symbol.species]() {
returnArray  }
}
constarr=newMyArray(1, 2, 3)
constnewArr=arr.map((x) =>x*2)
console.log(newArrinstanceofMyArray) // falseconsole.log(newArrinstanceofArray) // true

5. Symbol.match、Symbol.replace、Symbol.search和Symbol.split:

  • 当调用字符串的match、replace、search和split方法时,JavaScript引擎会查找传递给这些方法的参数是否有对应的Symbol属性。
  • 如果存在对应的Symbol属性,它应该是一个方法,用于自定义字符串的匹配、替换、搜索和分割逻辑。
  • JavaScript引擎将调用这些自定义方法来执行相应的操作。
classMyMatcher {
    [Symbol.match](str) {
returnstr.includes('hello');
    }
}
console.log('hello world'.match(newMyMatcher())); // true

总结

Symbol是ES6中引入的一种新的原始数据类型,用于创建唯一且不可变的标识符。它可以用作对象属性的键,解决属性名冲突的问题。Symbol还可以用于全局注册表、遍历对象属性和使用内置的Well-known Symbols等场景。

使用内置的Symbol属性时,JavaScript引擎会根据这些属性的特定用途来执行相应的操作。每个属性都有特定的行为规范,通过实现这些规范,我们可以自定义对象行为、扩展内置对象功能或实现特定功能。

目录
相关文章
|
6月前
|
JavaScript 前端开发
ES6:什么是Symbol?
ES6:什么是Symbol?
78 1
|
14天前
|
设计模式 JavaScript 前端开发
es6加上symbol的基础数据类型
【10月更文挑战第30天】ES6 中的 `Symbol` 作为一种新的基础数据类型,为 JavaScript 提供了一种创建唯一标识符和处理对象属性名冲突的有效方式,丰富了 JavaScript 的数据类型体系和编程模式,在实际开发中具有重要的应用价值。
|
14天前
|
设计模式 JavaScript 前端开发
es6加上symbol的基础数据类型
【10月更文挑战第22天】ES6中的 `Symbol` 作为一种新的基础数据类型,为JavaScript提供了一种创建唯一标识符和处理对象属性名冲突的有效方式,丰富了JavaScript的数据类型体系和编程模式,在实际开发中具有重要的应用价值。
|
4月前
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
54 1
|
4月前
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(一)
39 0
|
6月前
|
存储 JavaScript
ES6+新特性-Symbol与Set/Map数据结构
ES6 引入了三种新的数据结构:Symbol、Set和Map。Symbol是唯一且不可变的值,常用于定义对象的独特属性;Set存储不重复值,适合数组去重;Map则是键值对集合,键可为任意类型,提供了更灵活的存储方式。这些新数据结构提供了更高效的操作手段,分别解决了属性命名冲突、数据去重和复杂键值对存储的问题。示例展示了如何使用Symbol、Set和Map进行基本操作。
|
6月前
|
JavaScript
js开发:请解释什么是ES6的Symbol,以及它的用途。
ES6的Symbol数据类型创建唯一值,常用于对象属性键(防冲突)和私有属性。示例展示了如何创建及使用Symbol:即使描述相同,两个Symbol也不等;作为对象属性如`obj[symbol1] = &#39;value1&#39;`;也可作枚举值,如`Color.RED = Symbol(&#39;red&#39;)`。
54 4
|
6月前
ES6之Symbol
ES6之Symbol
|
6月前
|
JavaScript 前端开发
|
6月前
|
JavaScript 前端开发 开发者