目录

Symbol 类型

Symbol() 函数不可以 new

常用的内置符号 Symbol的工厂函数

1.Symbol.asyncIterator

2.Symbol.hasInstance

3.Symbol.isConcatSpreadable

4.Symbol.iterator

5.Symbol.match/replace/search/species/split


Symbol 类型

symbol的实例是唯一的不可变的, 用于确保对象的属性不重复

使用方式 : 调用 Symbol( 标识 ) 函数 返回一个符号

    const a = Symbol('a');const obj = {[a]: 1};console.log(obj);  // {Symbol(a): 1}

Symbol() 函数不可以 new

符号代表唯一的值, 但是我就想用一个符号呢 ?

通过 Symbol.for () 创建一个全局符号

    const a = Symbol('a');const b = Symbol.for('b');const b2 = Symbol.for('b');const obj = {[a]: 1,[b]: 2,[b2]: 3};console.log(b === b2); // trueconsole.log(obj); // {Symbol(a): 1, Symbol(b): 3}// key通过覆盖替换 不必疑惑// b 和 b2 指向同一个符号

通过 Symbol.keyFor () 查看全局符号 参数是全局符号 返回符号的描述

如果传的不是全局符号 返回undefined

如果传的不是符号 报错

const b = Symbol.for('b123');
console.log(Symbol.keyFor(b)); // b123

常用的内置符号 Symbol的工厂函数

1.Symbol.asyncIterator

此方法返回对象的默认的异步迭代器, 可由 for - await - of 使用

 // for await of 会调用对象以[Symbol.asyncIterator]为键的函数 该函数返回异步的generator
class Foo {constructor(n) {this.n = n;this.i = 0;}async *[Symbol.asyncIterator]() {while (this.i < this.n) {yield Promise.resolve(this.i++);}}}
​async function fn() {const p = new Foo(5);for await (const x of p) {console.log(x);}}fn()  // 0 1 2 3 4 

2.Symbol.hasInstance

该方法判断一个对象是不是构造函数的实例 , 由 instanceof 使用 , 也就是说 instanceof 检测数据类型时的原理就是调用了 Symbol.hasInstance

这个属性被定义在 Function 上 所以函数和类都有 Symbol.hasInstance 方法

    class Foo {static [Symbol.hasInstance]() {return false}}const demo = new Foo()console.log(Foo[Symbol.hasInstance](demo)); // falseconsole.log(demo instanceof Foo); // false
// 之所以会使false 是因为我重新定义了  [Symbol.hasInstance]() 函数   默认情况下是true

3.Symbol.isConcatSpreadable

这个符号作为属性返回一个布尔值 , 决定拼接数组时是否展开 , 默认为true

    let arr = [0];const arr1 = [1];arr1[Symbol.isConcatSpreadable] = true;const arr2 = [2];arr2[Symbol.isConcatSpreadable] = false;arr = arr.concat(arr1, arr2)console.log(arr); //  [0, 1, Array(1)]

4.Symbol.iterator

此方法返回对象默认的迭代器 for of 循环时就会调用对象的 Symbol.iterator函数(返回一个迭代器对象)

    class Foo {constructor(n) {this.n = n;this.i = 0;}*[Symbol.iterator]() {while (this.i < this.n) {yield this.i++;}}}async function fn() {const p = new Foo(5);for (const x of p) {console.log(x);}}fn()

5.Symbol.match/replace/search/species/split

Symbol允许我们自定义某些函数, 以改变函数原本的行为 .

接下来简单说明一下

match

match 方法返回字符串匹配正则表达式的结果
即使参数传入的不是正则表达式 也会调用 new RegExp('xxx') 转为正则表达式

原始的matchconst str = 'abcdefg';const reg = /b/;const res = str.match(reg);console.log(res);  // ['b', index: 1, input: 'abcdefg', groups: undefined]
自定义的matchconst str = 'abcdefg';const a = {[Symbol.match](target) {console.log(target);return false}};const res = str.match(a);console.log(res);  // false

replace

replace 方法传入的参数替换字符串匹配正则表达式的结果返回新的字符串
即使参数传入的不是正则表达式 也会调用 new RegExp('xxx') 转为正则表达式

原始的replacelet str = 'abcdefg';str = str.replace('abc', '111') // 等价于 str = str.replace(/abc/, '111')console.log(str); // '111defg'
自定义的replace// 自定义 replacelet str1 = '123';const target = [];target[Symbol.replace] = (...rest) => {return `${rest[1]}${rest[0]}`}console.dir(target);str1 = str1.replace(target, '333')console.log(str1); // 333123

search

search 方法传入的参数为目标字符中出现的位置  会调用参数的 Symbol.search 进行求值
即使参数传入的不是正则表达式 也会调用 new RegExp('xxx') 转为正则表达式

let str = 'abcdefg';const res = str.search('d');console.log(res); // 3// 自定义 search 方法const demo = {};demo[Symbol.search] = (target) => {return 5}console.log(str.search(demo)); 5// 执行原理  // 调用String.proptype.search() // 该方法调用正则表达式的[Symbol.search]console.log(String.prototype.search);console.log(RegExp.prototype[Symbol.search]);

species

如果你定义一个扩展数组类 那么这个类的实例对象默认是同时指向父类和Array这个构造函数
如果你想只返回Array替换掉他的父类  那么可以使用静态方法

// static get [Symbol.species]() {//   return Array;// }class Arr extends Array { };class Arr1 extends Array {static get [Symbol.species]() {return Array;}};const d1 = new Arr()console.log(d1.concat([]) instanceof Arr); // trueconsole.log(d1 instanceof Array); // trueconst d2 = new Arr1()console.log(d2.concat([]) instanceof Arr1); // falseconsole.log(d2 instanceof Array); // true

split

split() 方法以指定字符串分割调用对象, 在此方法调用时会使用以 Symbol.split 为键的函数

const str = 'abcd'const res = str.split('') // 等价于 str.split(new RegExp(''))console.log(res); // ['a', 'b', 'c', 'd']// 自定义 splitconst reg = new RegExp('')reg[Symbol.split] = (target) => {return 123}const res1 = str.split(reg)console.log(res1); // 123

6.Symbol.toPrimitive

对象转成字符串会被 String 函数转化成 '[object Object]'
如果想对对象进行加减运算 , 你可以通过定义 Symbol.toPrimitive 来实现

const obj = {};console.log(1 + obj);      // 1[object Object]console.log(1 - obj);      //  NaNconsole.log(String(obj));  //  [object Object]obj[Symbol.toPrimitive] = (hint) => {switch (hint) {case 'string':return '1';case 'number':return 0;default:return 'none'}}console.log(1 + obj);     // 1noneconsole.log(1 - obj);     //  1console.log(String(obj)); //  1

7.Symbol.toStringTag

对象使用 toString 方法时 会使用 Symbol.toStringTag 的返回值作为数组中的第二项 
我的理解就是 Symbol.toStringTag 方法可以改变(实例对象)的 toString 输出指定的构造函数

const obj1 = {}console.log(obj1.toString()); // [object Object]class P { }const obj2 = new P()console.log(obj2.toString()); // [object Object]obj2[Symbol.toStringTag] = 'P'console.log(obj2.toString()); // [object P]

8.Symbol.unscopables

在 with 语句中 访问的变量默认都会访问器参数对象的属性 
 使用 Symbol.unscopables 可以指定对象哪些属性不在with环境下生效

    // 例如const obj = {a: 'a',b: 'b'}obj[Symbol.unscopables] = {b: true}with (obj) {console.log(a);console.log(b); // 报错 b is not defined}

js中的symbol详解相关推荐

  1. computed用发_Vue.js中computed使用详解

    这次给大家带来Vue.js中computed使用详解,Vue.js中computed使用的注意事项有哪些,下面就是实战案例,一起来看一下. JS属性: JavaScript有一个特性是Object.d ...

  2. Js中apply方法详解说明

    Js apply 方法 详解 我在一开始看到JavaScript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了, ...

  3. JS中this关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 阅读此文章,还需要心平气和的阅读完,相信一定会有所收获,我也会不定期的发布,分享一些文章,共同学习 首先,必须搞清楚在JS里面,函数 ...

  4. JS中函数式编程详解版(FunctionalProgramming,FP)

    函数式编程详解 函数式编程的认识 函数式编程前置知识 函数是一等公民(First-class Function) 高阶函数 闭包 函数式编程基础 纯函数 lodash 模块 柯里化 函数组合 函子 函 ...

  5. JS中的showModelDialog详解和实例

    1.<a href="#" οnclick="SeePic('${list.PATH}')"><font color="blue&q ...

  6. JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解

    前  言 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于汇编语言这样的面 ...

  7. Vue.js-Day01-PM【事件绑定(事件传参、事件对象、传参+获取事件对象)、样式处理操作(模板、事件、属性绑定)、Tab切换(原生js实现、Vue.js实现)、js中的this详解关键字】

    Vue.js实训[基础理论(5天)+项目实战(5天)]博客汇总表[详细笔记] 目   录 4.事件绑定 4.1.事件绑定(点击.双击.鼠标移动) 点击按钮-最简单的事件绑定(无参函数) 格式 点击按钮 ...

  8. 【JS中scrollHeight/Width详解(不加定位的情况下)】

    scrollHeight和scrollWidth的详解 一. 内容块Y轴上没有超出的情况下 二.内容块Y轴上有超出的情况下 2.1 当 overflow-y: visible的情况 2.2 设置ove ...

  9. JS中Location使用详解

    javascript中 location用于获取或设置窗体的URL,并且可以用于解析URL,是BOM中最重要的对象之一,下面我们就来详细探讨下Location对象的使用. javascript中loc ...

  10. 前端基础知识点:JS中的参数传递详解

    JS语法中的传递参数,对于初学者是一个非常重要的概念.很多小伙伴在学习"值传递"和"引用传递"时,会有不少烦恼.今天我们就来通过各种姿势全方位剖析JS中的值传递 ...

最新文章

  1. laravel mysql sum查询并排行_必看!PHP常见面试题——MySQL篇(二)
  2. oracle数据泵数据库导出导入及定时备份
  3. 【转】 DOTA2中的伪随机及其lua实现
  4. workerman events.php,workerman安装event扩展的方法介绍
  5. docker 安装 vsftpd
  6. 00084_Map接口
  7. Leetcode--714. 买卖股票的最佳时间含手续费
  8. java xml date_W3C XML 模式时间数据类型与java Date进行转换
  9. [洪流学堂]Hololens开发高级篇1:凝视(Gaze)
  10. linux连接mysql_主机Navicat连接linux(虚拟机)的mysql数据库
  11. Python获取指定目录下文件数量及总大小
  12. 单片机(ISIS 7 Professional):简易LED警报灯代码项目
  13. uc看视频显示服务器有点忙,UC3软件常见问题处理方案
  14. 含8的数字的个数 (10分)
  15. 我的程序员成长之路——回顾自己三年的工作
  16. 01背包中背包装满和不装满
  17. wordpress搜索引擎蜘蛛统计插件SEO
  18. [HTML]入门小知识,列表?框架?表格?来吧。纯手工制作,满满都是智慧
  19. matlab试判断稳定性,MATLABsimulink稳定性分析时域分析
  20. 华硕ProArt 创16体验:全新交互+顶级屏幕 更匹配创作的笔记本

热门文章

  1. windows如何导出组策略结果集 (RSOP)
  2. dell云存储服务器,dell云存储服务器(戴尔存储服务器)
  3. 谈谈对腾讯360之争的观感
  4. 安卓apk360加固
  5. 解决vs编译后运行提示“系统找不到指定的文件”的问题
  6. 神经影像(核磁共振)概念及数据分析学习
  7. 谷歌统计代码使用方式
  8. 又是被打败的一天 (记招商银行笔试)
  9. php访问80端口强制跳转443,nginx 80端口重定向到443端口
  10. linux无法访问443端口,无法监听EC2上的https端口443(Amazon Linux)