百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Javascript ES6新引入的类型Symbol详解以及示例

toyiye 2024-06-23 18:39 12 浏览 0 评论

ES6引入的新的原始数据类型Symbol,表示独一无二的值,它是js中的第7种数据类型,是一种类似于字符串的数据类型。

Symbol特点:

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

2、Symbol值不能与其他数据进行运算。

3、Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。然后遍历。

如何创建?

可以使用函数创建。

let s = Symbol('demo');

或者

let s1 = Symbol.for('demo');

使用for函数可以得到某个字符串唯一的symbol值,例如下面的比较是相等的。

let s2 = Symbol.for('demo');

s1 === s2 返回的就是true。

Symbol内置的值

用做对象的属性。通过对这些内置值的设置,来改变对象在某些特定场景下的表现。

最常用的有:

  • Symbol.hasInstance

在使用instanceof操作符时调用。

class Person{

  static [Symbol.hasInstance](param){

  console.log(param);

  console.log('我被用来检查类型了')

  return false;

  }

}

let obj = {}

console.log(obj instanceof Person)
  • Symbol.isConcatSpreadable

使用concat来合并两个数组的时候,js会默认将数组内的元素展开然后合并为一个数组返回(原数组不变),这个行为es6以后可以使用Symbol.isConcatSpreadable改变,将其置为false就可以将数组作为一整个对象合并到过去。

let animals = ['cat','dog','panda']

let fruit = ['apple','pear']

fruit[Symbol.isConcatSpreadable] = true

console.log(animals.concat(fruit)) // 结果是['cat','dog','panda','apple','pear']

fruit[Symbol.isConcatSpreadable] = false

console.log(animals.concat(fruit)) // 结果是['cat','dog','panda', Array(2)]
  • Symbol.iterator

用于给对象定义迭代方法,这样就可以使用es6中新提供的for...of语法,需要注意的是,自定义的这个迭代器方法,需要按照一定的规范来写,需要返回一个具有next方法的对象,next方法需要返回具有value和done两个属性的对象。done会被用来判断什么时候结束迭代。

const banji = {

name: "终极一班",

stus: [ 'xiaoming', 'xiaoning', 'xiaotian', 'knight' ],

[Symbol.iterator]() {

// 索引变量

let index = 0;

// 保存this

let _this = this;

return {

next: function() {

if (index < _this.stus.length) {

const result = { value: _this.stus[index], done: false };

// 下标自增

index++;

// 返回结果

return result;

} else {

return { value: undefined, done: true };

}

}

};

}

}

// 遍历这个对象

for (let v of banji) {

console.log(v);

}
  • Symbol.match

一个在调用 String.prototype.match() 方法时调用的方法, 直白点说就是如果你定义一个字符串strValue,当你调用strValue.match(ObjectCase),如果ObjectCase这个对象定义了Symbol.match方法时,就会执行这个方法。

let animal = {

  [Symbol.match](str){

    console.log(str) //打印出字符串 cat

    return str.indexOf('animal');

  }

}

let kitty = "cat"

console.log(kitty.match(animal)) //返回值-1,这里打印出-1


  • Symbol.replace

一个在调用 String.prototype.replace() 方法时调用的方法,和上面的一样,当一个字符串调用strValue.replace(ObjectCase)时,会去执行ObjectCase中的Symbol.replace方法。

let animalName = {

  /* strValue 会返回调用者本身,replacement为调用repalce方法时传入的第二个参数 */

  [Symbol.replace](strValue, replacement){

    console.log("strValue: " + strValue,"replacement: " + replacement) //strValue: cat, its name is {params} replacement: {params}

    return strValue.replace("{params}", "kitty")

  }

}

let kitty = "cat, its name is {params}"

console.log(kitty.replace(animalName, "{params}")) //cat, its name is kitty
  • Symbol.search

一个在调用 String.prototype.search() 方法时调用的方法,用于在字符串中定位子串,这个也和上面str相关扩展一样直接看示例。

let animalName = {

/* strValue就是调用者本身 */

  [Symbol.search](strValue){

    console.log(strValue) //cat, its name is kitty

    return strValue.split("name is")[1]

  }

}

let kitty = "cat, its name is kitty"

console.log(kitty.search(animalName)) //kitty
  • Symbol.split

一个在调用 String.prototype.split() 方法时调用的方法,用于分割字符串。

let animalName = {

  /* strValue就是调用者本身 */

  [Symbol.split](strValue){

    console.log(strValue) //cat, its name is kitty

    return strValue.indexOf("name")

  }

}

let kitty = "cat, its name is kitty"

console.log(kitty.split(animalName)) //8
  • Symbol.toPrimitive

这个方法决定了当一个对象被转换为原始值时的行为。JavaScript引擎在每个类型值的原型上定义了Symbol.toPrimitive方法。这个方法被调用时,会接受一个字符串参数,表示当前运算的模式,一共有三种模式:

number: 该场景下需要转换成数值.对应操作符:* / -

string: 该场景下需要转换成字符串,显示使用string的构造方法

default:该场景下可以转换成数值,也可以转换成字符串,对应操作符:+

let obj = {

  [Symbol.toPrimitive](hint){

    switch(hint){

    case 'number':

    	return 123;

    case 'string':

    	return 'str';

    case 'default':

    	return 'default';

    default:

    	throw new Error();

    }

  }

}

console.log(2 * obj) //246

console.log(3 + obj) //3default

console.log(obj == 'default') //true

console.log(String(obj)) //str
  • Symbol.species

对象的Symbol.species属性,指向一个构造函数,创建衍生对象时,会使用该属性。这个的主要用途是,有些类库是在基类的基础上修改的,那么子类使用继承的方法时,作者可能希望返回基类的实例,而不是子类的实例。

class MyArray extends Array {

  static get [Symbol.species](){

    return Array;

  }

}

//b,c是a的衍生对象

const a = new MyArray(1,2,3)

const b = a.map(x => x+1)

const c = a.filter(x => x > 0)

//如果没有定义上面的Symbol.species,那么下面的instanceof均返回true

console.log(b instanceof MyArray) //true

console.log(c instanceof MyArray) //true

//定义了上面的Symbol.species时,返回值是下面这样

console.log(b instanceof MyArray) //false

console.log(b instanceof Array) //true
  • Symbol.toStringTag

一个在调用 String.prototype.toString() 方法时使用的字符串,用于创建对象描述。在对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串中,表示对象的类型。

//第一种写法,注意这里的get关键字是必须的,call方法需要用到get取值器

let animal = {

  get [Symbol.toStringTag](){

    return 'animal'

  }

}

console.log(Object.prototype.toString.call(animal)) // [object animal]

//第二种写法

console.log({[Symbol.toStringTag]: 'tag'}.toString()) // [object tag]
  • Symbol.unscopables

一个定义了一些不可被 with 语句引用的对象属性名称的对象集合。集合中的属性名称,会在with环境绑定中被排除。

const animal = {

  type: 'animal',

  name: 'kitty'

}

with(animal){

  console.log(type, name) //animal kitty

}

//定义Symbol.unscopables以便在with环境中排除某些属性

animal[Symbol.unscopables] = {

  type: true

}

with(animal){

  console.log(type) //Uncaught ReferenceError: type is not defined

}

以上这些被称为众所周知的symbols,其实其中很多值并不常用,为了验证这些symbols的准确用法,我搜了很多资料,总算把每一个都亲自验证了一遍。

这里附上一个地址,这里面有特别详细的示例代码,我也是自己费了半天劲儿快验证完的时候才发现这个网址的,白白浪费了好多时间。

大家百度搜索一下关键字Symbol MDN ,可以看到有mozilla的一个开发者网站,这上面也有可以参考的示例。

另外,之所以要研究这个,主要是最近在学vue3 + typescript,身为一个没太多基础的前端小白,学习的过程中遇到一个知识点可能都会要查半天资料才能弄懂,不过我也乐在其中。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码