当前位置: 移动技术网 > IT编程>开发语言>Java > ES6——符号Symbol

ES6——符号Symbol

2020年08月10日  | 移动技术网IT编程  | 我要评论
符号一、普通符号1.创建一个符号2.符号的特点二、共享符号1.基础2.实现三、知名符号1.Symbol.hasInstance2.Symbol.isConcatSpreadable一、普通符号符号是ES6新增的一个数据类型,它通过使用函数 Symbol(符号描述)来创建1.创建一个符号const syb1 = Symbol();const syb2 = Symbol("abc");console.log(syb1, syb2);2.符号的特点符号设计的初衷,是为了给对象设置私有属性这里

一、普通符号

符号是ES6新增的一个数据类型,它通过使用函数 Symbol(符号描述)来创建

1.创建一个符号

const syb1 = Symbol();
const syb2 = Symbol("abc");
console.log(syb1, syb2);

在这里插入图片描述

2.符号的特点

符号设计的初衷,是为了给对象设置私有属性
这里设一个游戏类函数,如下:一个人物的伤害通过调用处理函数对攻击力进行处理。

class Hero {
    constructor(attack...) {
        this.attack = attack;//攻击力
        ...
    };
    gongji() {
        //伤害:攻击力*随机数(0.8~1.1)
        const dmg = this.attack * this.getRandom(0.9, 1.1);
        console.log(dmg);
    };
    getRandom(min, max) { 
        //根据最小值和最大值产生一个随机数
        return Math.random() * (max - min) + min;
    };
};

对于编程来说,我们只希望getRandom函数最好只能有gongji函数调用(变量私有化)。那么符号就可以很好解决这个问题。

  1. 没有字面量
  2. 使用 typeof 得到的类型是 symbol
const syb1 = Symbol();
const syb2 = Symbol("abc");
console.log(syb1, syb2);
console.log(typeof syb1 === "symbol", typeof syb2 === "symbol");
  1. 每次调用 Symbol 函数得到的符号永远不相等,无论符号名是否相同
const syb1 = Symbol("符号");
const syb2 = Symbol("符号");
console.log(syb1 === syb2);//false
  1. 符号可以作为对象的属性名存在,这种属性称之为符号属性
    1. 开发者可以通过精心的设计,让这些属性无法通过常规方式被外界访问
    2. 符号属性是不能枚举的,因此在 for-in 循环中无法读取到符号属性,Object.keys 方法也无法读取到符号属性
    3. Object.getOwnPropertyNames 尽管可以得到所有无法枚举的属性,但是仍然无法读取到符号属性
    4. ES6 新增 Object.getOwnPropertySymbols 方法,可以读取符号
  2. 符号无法被隐式转换,因此不能被用于数学运算、字符串拼接或其他隐式转换的场景,但符号可以显式的转换为字符串,通过 String 构造函数进行转换即可,console.log 之所以可以输出符号,是它在内部进行了显式转换
const Hero = (() => {
    const getRandom = Symbol();//立即执行后就消失了
    return class {
        constructor(attack) {
            this.attack = attack;
			...
        }
        gongji() {
            //伤害:攻击力*随机数(0.9~1.1)
            const dmg = this.attack * this[getRandom](0.9, 1.1);
            console.log(dmg);
        }
        [getRandom](min, max) { //根据最小值和最大值产生一个随机数
            return Math.random() * (max - min) + min;
        }
    }
})();

const h = new Hero(3);
console.log(h);
h.gongji();
h[getRandom](0.9,1.1);//无法被调用

在这里插入图片描述

const syb = Symbol();
const obj = {
    [syb]: 1,
    a: 2,
    b: 3
};
for (const prop in obj) {
    console.log(prop);
};
console.log(Object.keys(obj));
console.log(Object.getOwnPropertyNames(obj));
//得到的是一个符号属性的数组
const sybs = Object.getOwnPropertySymbols(obj);//该方法可以查看
console.log(sybs, sybs[0] === syb);

在这里插入图片描述

const Hero = (() => {
    const getRandom = Symbol();
    return class {
        constructor(attack, hp, defence) {
            this.attack = attack;
            this.hp = hp;
            this.defence = defence;
        }

        gongji() {
            //伤害:攻击力*随机数(0.8~1.1)
            const dmg = this.attack * this[getRandom](0.8, 1.1);
            console.log(dmg);
        }
        [getRandom](min, max) { //根据最小值和最大值产生一个随机数
            return Math.random() * (max - min) + min;
        }
    }
})();
const h = new Hero(3, 6, 3);
const sybs = Object.getOwnPropertySymbols(Hero.prototype);
const prop = sybs[0];
console.log(h[prop](3, 5));//实在需要调用时,可以选择调用

二、共享符号

1.基础

根据某个符号名称(符号描述)能够得到同一个符号

const syb1 = Symbol.for("abc");
const syb2 = Symbol.for("abc");
console.log(syb1 === syb2)
const obj1 = {
    a: 1,
    b: 2,
    [syb1]: 3
}
const obj2 = {
    a: "a",
    b: "b",
    [syb2]: "c"
}
console.log(obj1, obj2);

在这里插入图片描述

const obj = {
    a: 1,
    b: 2,
    [Symbol.for("c")]: 3
};
console.log(obj[Symbol.for("c")]);//只要符号名称一样,就可以调用了

2.实现

const SymbolFor = (() => {
    const global = {};//用于记录有哪些共享符号
    return function (name) {
        console.log(global)
        if (!global[name]) {
            global[name] = Symbol(name);
        }
        console.log(global);
        return global[name];
    }
})();
const syb1 = SymbolFor("abc");
const syb2 = SymbolFor("abc");
console.log(syb1 === syb2);

三、知名符号

知名符号是一些具有特殊含义的共享符号,通过 Symbol 的静态属性得到

1.Symbol.hasInstance

该符号用于定义构造函数的静态成员,它将影响 instanceof 的判定

function A() {

}
const obj = new A();
console.log(obj instanceof A);//true
//等效于A[Symbol.hasInstance](obj)或Function.prototype[Symbol.hasInstance]
function A() {

};
Object.defineProperty(A, Symbol.hasInstance, {
    value: function (obj) {
        return false;
    }
});
const obj = new A();
console.log(obj instanceof A);//false

2.Symbol.isConcatSpreadable

const arr = [3];
const arr2 = [5, 6, 7, 8];
arr2[Symbol.isConcatSpreadable] = true;
const result = arr.concat(56, arr2)
console.log(result);//

在这里插入图片描述

arr2[Symbol.isConcatSpreadable] = false;

在这里插入图片描述

const arr = [1];
const obj = {
    0: 3,
    1: 4,
    length: 2,
    [Symbol.isConcatSpreadable]: true
}
const result = arr.concat(2, obj)
console.log(result);

在这里插入图片描述

本文地址:https://blog.csdn.net/xun__xing/article/details/107892783

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网