ES6新增数据类型(Symbol)

ES6新增数据类型(Symbol)

基本(原始)类型和引用类型介绍
在了解Symbol之前,我们需要了解下JS的数据类型,在JS中数据类型分为两类:基本(原始)类型和引用类型。

  • 基本(原始)类型:数值型(Number),字符类型(String),布尔值型(Boolean),null 和 underfined
  • 引用类型:对象(Object)

那es6新增的Symbol是什么类型呢? 这里Symbol也是基本类型;

概述
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。

	let syb1 = Symbol();
	let syb2 = Symbol();
	
	console.log(syb1)  // Symbol()
	console.log(typeof syb1)  // 'symbol'
	console.log(syb1 == syb2) // false
	console.log(syb1 === syb2) // false

由此可见,即使Symbol的描述值参数相同,它们的值也不相同,描述值仅仅是起描述的作用,不会对Symbol值本身起到任何的改变。关于描述值需要注意的一点:接受除Symbol值以外所有的值

	let s1 = Symbol('foo');
	let s2 = Symbol('bar');
	let s3 = Symbol(3.6);
	let s4 = Symbol({foo:'bar'});
	
	console.log(s1) // Symbol(foo)
	console.log(s2) // Symbol(bar)
	console.log(s1.toString()) // "Symbol(foo)"
	console.log(s2.toString() )// "Symbol(bar)"
	console.log(s3) //Symbol(3.6)
	console.log(s4) //Symbol([object Object])

为什么Symbol是基本(值)类型,而不是引用类型。Symbol函数并不是构造函数,因此不能使用new方法来生成一个Symbol对象,否则编译器会抛出异常,如执行下段代码所示:

	new Symbol	//TypeError: Symbol is not a constructor
  • Symbol 值不能与其他类型的值进行运算,会报错
  • symbol 得到的符号永远不会相等,不管符号名是否相同
  • Symbol 值可以显式转为字符串、也可以转为布尔值,但是不能转为数值
  • 在ES2019中增加了一个description可用于读取Symbol的描述.description

作为属性名
由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。

	const syb1 = Symbol("即将用于对象的属性名");
	const obj = {
		 a : 1,
		 b : 2,
		 [syb1] : 3
	}
	console.log(obj[syb1])	//3
  • Symbol 作为对象属性名时不能用.运算符,要用方括号
  • Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问

属性名的遍历
Symbol 作为属性名不会被遍历的几种方法:

  • for…in、for…of循环中
  • Object.keys()
  • Object.getOwnPropertyNames()

Symbol作为属性名可以被查询的:

  • Object.getOwnPropertySymbols()

    该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值

定义一个私有方法

		const Hero = ( () =>{
            const getli = Symbol();		//方法名
            return  class Hero{
                constructor(gong,fang,hp){
                    this.gong = gong;
                    this.fang = fang;
                    this.hp = hp; 
                }
                getgong(){
                    console.log(this.gong * this.getli(0.8,1.1))
                }
                [getli](min,max){
                    return Math.random() * (max - min) + min; 
                }
            }
        
        } )()

        const hero = new Hero(50,10,1000);
        console.log(hero)	//Hero {gong: 50, fang: 10, hp: 1000}

Symbol.for(),Symbol.keyFor()

  • Symbol.for(): 重新使用同一个 Symbol 值

它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局

	let syb1 = Symbol.for('foo');
	let syb2 = Symbol.for('foo');
	
	syb1 === syb2 // true
  • Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key
	let syb1 = Symbol.for("foo");
	Symbol.keyFor(syb1) // "foo"
	
	let syb2 = Symbol("foo");
	Symbol.keyFor(syb2) // undefined

知名符号(特殊的共享符号)

  1. Symbol.hasInstance 可以去影响instanceof的值,该方法会因为instanceof语句的使用而被调用,来检查一个对象是否是某一个类的实例。
 		function A() {}
        const a = new A();
        
        console.log(a instanceof A);    //true
		console.log(A[Symbol.hasInstance](a));  //true
		function A() {}
        const a = new A();
        
        Object.defineProperty(A,Symbol.hasInstance, {
			value : function(){
				return false;
			}
		})

        console.log(a instanceof A);    //false
		console.log(A[Symbol.hasInstance](a));  //false
  1. Symbol.isConcatSpreadable 可以去配置数组的concat方法以什么方式拼接,用于为对象定义一个属性
		const arr1 = [1,2,3];
        const arr2 = [4,5,6];
        arr2[Symbol.isConcatSpreadable] = false;
        const arr3 = arr1.concat(arr2);
        console.log(arr3)	// [1, 2, 3, [4,5,6]]
  1. Symbol.toPrimitive 该方法会在该对象需要转换为值类型的时候被调用,可以根据程序的行为决定该对象需要被转换成的值。
		const obj = {
		    a: 1,
		    b: 2
		}
		// obj[Symbol.toPrimitive] = function() {
		//     return 100;
		// }
		console.log(obj + 123); 
		console.log(obj * 123); 

		class Temperature {
		    constructor(degree) {
		        this.degree = degree;
		    }
		        [Symbol.toPrimitive](type) {
		            console.log(type)
		            if (type === "default") {
		                return this.degree + "摄氏度";
		            } else if (type === "number") {
		                return this.degree;
		            } else if (type === "string") {
		                return this.degree + "℃"
		            }
		        }
		}
		const t = new Temperature(30);
		// console.log(t + 1)
		console.log(String(t))
  1. Symbol.toStringTag 该知名符号会影响Object.prototype.toString 的返回值
		class A{
            [Symbol.toStringTag] = 'hello'
        }
        const a = new A();
        console.log(a);		//A {Symbol(Symbol.toStringTag): "hello"}
        console.log(Object.prototype.toString.call(a));	//[object hello]
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值