Symbol

148 阅读1分钟
// basic 
let myName = Symbol('chris');
console.log(typeof myName); // Symbol

let obj1 = {};
obj1[myName] = 'javascript';

console.log(obj1[myName]); // javascript

console.log('--------------------------');

/**
 * Symbol for 全局共享
 * 创建时,先检查全局是否存在这个key的Symbol
 * 如果存在则直接返回这个Symbol
 * 不存在则创建,并在全局注册
 */

let uid = Symbol.for('uid');
let obj2 = {
    [uid]: '20210803'
};
console.log(obj2[uid]); // 20210803
console.log(uid); // Symbol(uid)

let uid2 = Symbol.for('uid');
console.log(uid2 === uid); // true
console.log(obj2[uid2]); // 20210803
console.log(uid2); // Symbol(uid)

console.log('--------------------------');

/**
 * symbol keyfor
 * 全局注册表中不存在共享的symbol时,则取不出对应的key
 */
let uid3 = Symbol.for('uid');
console.log(Symbol.keyFor(uid3)); // uid

let uid4 = Symbol.for('uid');
console.log(Symbol.keyFor(uid4)); // uid

let uid5 = Symbol('uid');
console.log(Symbol.keyFor(uid5)); // undefined

console.log('--------------------------');

/**
 * symbol不可强制转换
 */
let uid6 = Symbol('uid');
// uid6 + ''; // TypeError: Cannot convert a Symbol value to a string

console.log('--------------------------');

/**
 * obj中symbol key的获取
 */
let uid7 = Symbol('uid');
let obj = {
    [uid]: 'uid'
};
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(uid)]

console.log('--------------------------');

/**
 * Symbol.hasInstance
 */
function Func() {}
const func = new Func;
console.log(func instanceof Func); // true
console.log(Func[Symbol.hasInstance](func)); // true
Object.defineProperty(Func, Symbol.hasInstance, {
    value: (value) => Boolean(value)
})
const anotherFunc = new Func;
console.log(anotherFunc instanceof Func); // true
console.log( 0 instanceof Func); // false
console.log(1 instanceof Func); // true

console.log('--------------------------');

/**
 * Symbol.isConcatSpreadable
 */
let obj3 = {
    0: 'first',
    1: 'second',
    length: 2,
    [Symbol.isConcatSpreadable]: true
}
console.log(['arrs'].concat(obj3)); // [ 'arrs', 'first', 'second' ]

console.log('--------------------------');

/**
 * Symbol.toPrimitive
 * 类型转换时,对象转换成原始类型,
 * toPrimitive调用一个hint参数,参数值:number,string,default
 */
let obj4 = {
    valueOf: function() {
        console.log('valueOf');
    },
    toString: function() {
        console.log('toString');
    }
}
obj4 + 2; // valueOf
obj4  == 2; // valueOf
Number(obj4); // valueOf
String(obj4); // toString

function Temperature(degrees) {
    this.degrees = degrees;
}

Temperature.prototype[Symbol.toPrimitive] = function(hint) {
    console.log('hint is ', hint);
}

let freezing = new Temperature(32);

freezing + 2; // hint is  default
freezing / 2; // hint is  number

console.log('--------------------------');

/**
 * Symbol.iterator
 */
let ar = ['javascript'];
let art = ar[Symbol.iterator]();
console.log(ar); // Object [Array Iterator] {}
console.log(art.next()); // { value: 'javascript', done: false }
console.log(art.next()); // { value: undefined, done: true }

let str = 'string';
let strIt = str[Symbol.iterator]();
console.log(strIt); // Object [String Iterator] {}

// let o = { name: 'js'};
// let oit = o[Symbol.iterator](); // o[Symbol.iterator] is not a function
// console.log(oit);

let range = {
    from: 1,
    to: 5
}

range[Symbol.iterator] = function() {
    return {
        current: this.from,
        last: this.to,

        next() {
            if (this.current <= this.last) {
                return {done: false, value: this.current++ };
            } else {
                return { done: true };
            }
        }
    }
}

// 1 2 3 4 5
for(let num of range) {
    console.log(num);
}

let o = {
    0: '000',
    3: '333',
    length: 6
}

// for(let value of o) {} // o is not iterable

let oit = Array.from(o);
for(let value of oit) {}

let ranger = Array.from(range);
console.log(ranger); // [ 1, 2, 3, 4, 5 ]