ECMAScript 6+ 新特性 ( 三 ) Symbol 唯一值类型

2.13.Symbol ***

2.13.1.Symbol基本定义

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。

它可以用作对象属性的键,用于创建私有属性和方法,以及用于创建唯一的标识符等。

Symbol 值通过内置的 Symbol 函数来创建,并且每个 Symbol 值都是唯一的,不会重复。这意味着任何两个 Symbol 值都不相等。

它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

//创建Symbol
// let s = Symbol();
// console.log(s, typeof s);  // 输出 :  Symbol() 'symbol'

// 描述只是作为可选参数提供的一个字符串,仅用于调试和标识目的,并不影响 Symbol 的唯一性。
let s2 = Symbol('独一无二的');
let s3 = Symbol('独一无二的');

console.log(s2 === s3); // false

2.13.2.Symbol 的特点

2.13.2.1.防止对象属性名冲突

Symbol 的值是唯一的,用来解决命名冲突的问题

const mySymbol = Symbol('myKey');
const obj = {};
// 可以避免与(可能存在的)原属性myKey 冲突
obj[mySymbol] = 'Hello, Symbol!';

console.log(obj[mySymbol]); // 输出: "Hello, Symbol!"

在这个例子中,我们使用 Symbol 作为对象属性名,由于 Symbol 的唯一性,即使在其他地方也定义了名为 myKeySymbol,它们也是互不干扰的。

注 : 遇到唯一性的场景时要想到 Symbol

2.13.2.2.Symbol 值不能与其他数据进行运算, 报错
let s = Symbol();   

let result = s + '100';  // Uncaught TypeError: Cannot convert a Symbol value to a string
let result = s + 100;  // Uncaught TypeError: Cannot convert a Symbol value to a number
let result = s > 100; // Uncaught TypeError: Cannot convert a Symbol value to a number
let result = s + s; // Uncaught TypeError: Cannot convert a Symbol value to a number
2.13.2.3.( ES 10 ) description属性

获取信息

let s = Symbol();  
let s2 = Symbol('独一无二的');

console.log(s.description) // undefined
console.log(s2.description) // 独一无二的

2.13.3.Symbol.for()

当你调用 Symbol.for(key) 时,它会检查全局 Symbol 注册表中是否存在以 key 为键的 Symbol。如果存在,则返回该 Symbol;如果不存在,则会在注册表中创建一个新的 Symbol(其描述为 key),并将其关联到给定的键,然后返回这个新创建的 Symbol

这样做的好处是,即便在不同的模块或者上下文中,只要 Symbol.for() 的参数相同,就会返回同一个 Symbol 实例,这有利于跨模块共享和识别 Symbol。

// //Symbol.for 创建
let s4 = Symbol.for('独一无二的');
let s5 = Symbol.for('独一无二的');
console.log(s4 === s5);  // true

2.13.3.创建私有属性和方法

//向对象中添加方法 study eat        
let stu = {
    name:'王小二',
    study: function(){},
    eat: function(){}
};
// 声明一个对象
let methods = {
    study: Symbol(),
    eat: Symbol()
};
stu[methods.study] = function(){
    console.log("我努力学习");
}
stu[methods.eat] = function(){
    console.log("我饿了就吃!!");
}
console.log(stu);
stu[methods.study]()
stu[methods.eat]()

这段代码的主要目的是在 stu 对象中添加名为 studyeat 的方法,

但在添加时不清楚, 对象中是否已经有了这两个方法, 如果直接添加就会覆盖原方法

使用了 Symbol 类型的键来定义这些方法,以实现私有或隐藏属性的效果。

声明了一个名为 methods 的对象,其中包含两个 Symbol 类型的属性:studyeat

然后,将新的方法赋值给 stu 对象,但是使用了 methods 对象中的 Symbol 键:stu[methods.study] stu[methods.eat]

这样stu 就有 4个函数 study , eat , stu[methods.study] , stu[methods.eat]

在控制台输出时,由于 Symbol 键不可枚举,因此我们无法直接看到 methods.studymethods.eat 关联的方法。

这种使用 Symbol 创建“私有”方法的方式可以避免外部代码误操作或意外访问到这些方法,增强了代码的安全性和封装性。

若要调用这些方法,需要知道对应的 Symbol 键,例如:stu[methods.study]()stu[methods.eat]()

2.13.4.Symbol 内置值***

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。

可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。

2.13.4.1.Symbol.hasInstance

当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法

class Stu{
    static [Symbol.hasInstance](param){
        console.log(param);
        console.log("我被用来检测类型了");
        return false;
    }
}

let o = {};

console.log(o instanceof Stu);
2.13.4.2.Symbol.iterator

对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器

let myArray = ['a', 'b', 'c'];
let iterator = myArray[Symbol.iterator]();
iterator.next(); // { value: "a", done: false }
2.13.4.3.Symbol.toPrimitive

该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。

let obj = {
  [Symbol.toPrimitive](hint) {
    if (hint === 'string') {
      return 'converted to string';
    }
    // ...
  }
};

String(obj); // 'converted to string'
2.13.4.4.Symbol.isConcatSpreadable

对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。

const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));
2.13.4.5.Symbol.species

创建衍生对象时,会使用该属性

2.13.4.6.Symbol.match

当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。

2.13.4.7.Symbol.replace

当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。

2.13.4.8.Symbol.search

当该对象被 str.search (myObject)方法调用时,会返回该方法的返回值。

2.13.4.9.Symbol.split

当该对象被 str.split(myObject)方法调用时,会返回该方法的返回值。

2.13.4.10.Symbol. toStringTag

在该对象上面调用 toString 方法时,返回该方法的返回值

2.13.4.11.Symbol. unscopables

该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值