Js中Symbol的静态属性及用途详解

 更新时间:2023年12月15日 10:02:02   作者:慕仲卿  
JavaScript 语言在 ES6 规范中引入了 Symbol 类型,它是一种原始数据类型,用于创建唯一的标识符,本文将介绍 Symbol 类型的所有静态属性,并举例说明它们的用途和使用场景,希望对大家有所帮助

Js Symbol的静态属性及用途

JavaScript 语言在 ES6 规范中引入了 Symbol 类型,它是一种原始数据类型,用于创建唯一的标识符。Symbol 对象是不可改变且唯一的,适合用作对象属性的键。除了作为对象的属性键之外,Symbol 还有许多静态属性(也称为“内置符号”或“众所周知的符号”),这些属性包含了与语言内部机制相关联的特殊符号值。本文将介绍 Symbol 类型的所有静态属性,并举例说明它们的用途和使用场景。

Symbol.hasInstance

Symbol.hasInstance 属性用来定制 instanceof 运算符,在一个构造器对象上使用 instanceof 时会调用这个方法。

class MyClass {
    static [Symbol.hasInstance](instance) {
        return Array.isArray(instance);
    }
}
console.log([] instanceof MyClass); // true

在这个例子中,MyClass 用自定义的 Symbol.hasInstance 函数覆盖了默认行为,检查对象是否为数组,从而使得数组实例在 instanceof 运算时返回 true

Symbol.isConcatSpreadable

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

let collection = {
    0: 'hello',
    1: 'world',
    length: 2,
    [Symbol.isConcatSpreadable]: true
};
console.log(['Hi'].concat(collection)); // ['Hi', 'hello', 'world']

在这个例子中,collection 对象通过设置 Symbol.isConcatSpreadabletrue,可以被 concat 方法展开并合并到结果数组中。

Symbol.iterator

Symbol.iterator 属性指向对象的默认迭代器方法,通常用于定义对象的 for-of 循环行为。

let fibonacci = {
  [Symbol.iterator]() {
    let pre = 0, cur = 1;
    return {
      next() {
        [pre, cur] = [cur, pre + cur];
        return { done: false, value: cur };
      }
    };
  }
}
for (let n of fibonacci) {
  if (n > 1000) break;
  console.log(n);
}

上述代码中定义了斐波那契序列的迭代器,可以通过 for-of 循环输出序列中的数。

Symbol.match

Symbol.match 属性用于定义匹配的正则表达式行为,即当一个对象被 String.prototype.match() 方法调用时所执行的操作。

let hasNumber = {
    [Symbol.match](string) {
        return /\d+/.test(string);
    }
};
console.log('123'.match(hasNumber)); // true

在这个例子中,hasNumber 定义了一个自定义的 match 行为,当字符串中包含数字时返回 true

Symbol.replace

Symbol.replace 属性定义了当一个对象被 String.prototype.replace() 方法调用时如何替换字符串中的匹配部分。

let replaceHyphens = {
    [Symbol.replace](string, replacer) {
        return string.replace(/-/g, replacer);
    }
};
console.log('123-45-678'.replace(replaceHyphens, ':')); // '123:45:678'

这个例子中,replaceHyphens 将字符串中的所有连字符替换为冒号。

Symbol.search

Symbol.search 属性定义了当 String.prototype.search() 方法被调用时,如何返回字符串中匹配项的索引。

let searchObject = {
    [Symbol.search](string) {
        return string.indexOf('JavaScript');
    }
};
console.log('Hello JavaScript!'.search(searchObject)); // 6

在这个例子中,searchObject 实现了搜索 "JavaScript" 字符串并返回它在源字符串中的位置。

Symbol.species

Symbol.species 属性用于创建派生对象时确定默认的构造函数。

class MyArray extends Array {
  static get [Symbol.species]() { return Array; }
}
let a = new MyArray(1,2,3);
let mapped = a.map(x => x * x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array);   // true

这个例子表明,MyArray 创建的新数组 mapped 不是 MyArray 的实例,它是 Array 的实例。

Symbol.split

Symbol.split 属性定义当一个对象被 String.prototype.split() 方法调用时,如何分割字符串。

let splitByLength = {
    [Symbol.split](string) {
        return string.length <= 3 ? [string] : [string.slice(0, 3), string.slice(3)];
    }
};
console.log('JavaScript'.split(splitByLength)); // ['Jav', 'aScript']

在这个例子中,splitByLength 对象根据长度进行分割,将字符串分为长度不超过3的部分。

Symbol.toPrimitive

Symbol.toPrimitive 属性用于指定对象转换为相应的原始值时的行为。

let obj = {
    [Symbol.toPrimitive](hint) {
        if (hint === 'number') {
            return 42;
        }
        if (hint === 'string') {
            return 'fourty two';
        }
        return true;
    }
};
console.log(+obj);  // 42
console.log(`${obj}`); // 'fourty two'

在这个例子中,根据转换提示(hint),obj 对象会返回不同的原始值。

Symbol.toStringTag

Symbol.toStringTag 属性用于自定义对象的默认字符串描述,是在对象上调用 toString 方法时使用的。

let myCollection = {
    get [Symbol.toStringTag]() {
        return 'MyCollection';
    }
};
console.log(myCollection.toString()); // [object MyCollection]

myCollection 对象的 toString 方法返回了自定义的字符串描述 [object MyCollection]

Symbol.unscopables

Symbol.unscopables 属性指出了哪些属性名会被 with 环境绑定排除。

Array.prototype[Symbol.unscopables] = Object.assign({}, Array.prototype[Symbol.unscopables], {
    map: true
});
with ([]) {
    console.log(map); // ReferenceError: map is not defined
}

这个例子通过把 Array.prototype.map 方法标记为 unscopables,在 with 语句中无法直接使用 map 方法。

总结

由于 Symbol 类型的不可变和唯一性质,它的内置符号作为语言的元操作部分,扮演了调整对象默认行为的关键角色。无论是改变内置操作的工作方式,还是定义新的行为,Symbol 的静态属性为自定义高级抽象提供了强大的支持,极大地增强了语言的灵活性和扩展性。在日益复杂的应用开发中,了解并合理应用 Symbol 的静态属性,有助于提高代码的可维护性和扩展性。

到此这篇关于Js中Symbol的静态属性及用途详解的文章就介绍到这了,更多相关Js Symbol内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • XML+XSL 与 HTML 两种方案的结合

    XML+XSL 与 HTML 两种方案的结合

    XML+XSL 与 HTML 两种方案的结合...
    2007-04-04
  • JavaScript中DOM常见的操作汇总

    JavaScript中DOM常见的操作汇总

    DOM(文档对象模型)是一种用于表示和操作HTML和XML文档的标准,在JavaScript中,可以使用DOM API来对DOM进行操作,下面就来看看常见的操作都有哪些吧
    2023-08-08
  • js 使FORM表单的所有元素不可编辑的示例代码

    js 使FORM表单的所有元素不可编辑的示例代码

    使FORM表单的的所有元素不可编辑的方法有很多,在本文将为大家详细介绍下,js是如何做到的,感兴趣的朋友不要错过
    2013-10-10
  • JS实现的随机排序功能算法示例

    JS实现的随机排序功能算法示例

    这篇文章主要介绍了JS实现的随机排序功能算法,结合具体实例形式分析了javascript常用的排序算法实现技巧,需要的朋友可以参考下
    2017-06-06
  • JS实现数组去重及数组内对象去重功能示例

    JS实现数组去重及数组内对象去重功能示例

    这篇文章主要介绍了JS实现数组去重及数组内对象去重功能,结合实例形式分析了ES5与ES6两种版本针对数组去重的相关操作技巧,需要的朋友可以参考下
    2019-02-02
  • 禁止弹窗中蒙层底部页面跟随滚动的几种方法

    禁止弹窗中蒙层底部页面跟随滚动的几种方法

    我们大家在做弹出层的时候,必不可少的一个元素就是蒙层,也就是遮罩层,当弹出层滚动的时候,蒙层底部的页面一般是要求固定不动的,所以这篇文章就来给大家介绍了如何禁止弹窗中蒙层底部页面跟随滚动的几种方法,需要的朋友可以参考下。
    2017-12-12
  • JS中进行字符串替换的方法

    JS中进行字符串替换的方法

    replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串,这篇文章主要介绍了js中进行字符串替换的方法,需要的朋友可以参考下
    2024-01-01
  • 微信小程序获取用户头像昵称组件封装实例(最新版)

    微信小程序获取用户头像昵称组件封装实例(最新版)

    我们在进行小程序开发的时候,往往需要获取微信用户的部分个人信息,常见的有用户头像,昵称等,下面这篇文章主要给大家介绍了关于微信小程序获取用户头像昵称组件封装的相关资料,需要的朋友可以参考下
    2022-12-12
  • 微信小程序自定义底部、顶部、中间、左边及右边弹窗

    微信小程序自定义底部、顶部、中间、左边及右边弹窗

    这篇文章主要给大家介绍了关于微信小程序自定义底部、顶部、中间、左边及右边弹窗的相关资料,弹窗是小程序中非常重要的一种互动方式,比如用户注册时错误提示、优惠券领取提示、签到成功提示等等,需要的朋友可以参考下
    2023-11-11
  • 给文字加上着重号的JS代码

    给文字加上着重号的JS代码

    这篇文章介绍了给文字加上着重号的JS代码,有需要的朋友可以参考一下
    2013-11-11

最新评论