作者:xiaohesong
连接:https://juejin.im/post/6844903703242080263
原文连结:https://xiaohesong.gitbook.io/today-i-learn/front-end/es6/understanding-es6/symbol#basic
来源:掘金
Symbol是ES6加进来的,也是属於基本类型(number、string....)
可以发现Symbol类型可以当作对象的key
let foo = Symbol('bar')
console.log(typeof foo) // 'symbol'
let testObj = {}
testObj[foo] = '这样可以设置!'
console.log(testObj);
透过这个方法创建时会先在全局里面寻找这个key的Symbol,如果存在则返回此Symbol,不存在则创建并进行全局注册
// 用基本方法创建两个相同key的Symbol会不一样
let first = Symbol('不会一样')
let second = Symbol('不会一样')
console.log(first === second); // fasle
// 用此方法创建的则会一样
let fooA = Symbol.for('居然会一样')
let fooB = Symbol.for('居然会一样')
console.log(fooA === fooB); // true
// 基础方法跟Symbol.for当然也不一样
let barA = Symbol('这样也会不一样')
let barB = Symbol.for('这样也会不一样')
console.log(barA === barB); // false
返回用全局注册Symbol的key
let fooA = Symbol.for("foo");
console.log(Symbol.keyFor(fooA)); // "foo"
let fooB = Symbol.for("foo");
console.log(Symbol.keyFor(fooB)); // "foo"
// 因为没有透过Symbol.for进行全局注册当然找不到
let notKeyCreated = Symbol("我居然会不存在!");
console.log(Symbol.keyFor(notKeyCreated)); // undefined
可以透过String转型,不过讲真的这样做意义不大
let foo = Symbol('foo')
console.log(String(foo));
console.log(foo.toString())
console.log(foo + '');
let foo = Symbol('foo')
let obj = {
// 注意我们要用Symbol当成key,需要要用方括号刮起来
// 因为需要的是变量foo非字符串foo
[foo]: 'foo'
}
console.log(Object.keys(obj)) // []
console.log(Object.getOwnPropertyNames(obj)) // []
// ES6新增的方法
console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(foo)]
let obj = {
[foo]: 'foo'
}
这里提到了我们要让
注意我们要用Symbol当成key,需要用方括号刮起来
因为需要的是变量foo非字符串foo
所以以下设置也是为了此目的
let obj = {}
let foo = Symbol('foo')
obj.foo = 'foo'
obj[foo] = 'SymbolFoo'
console.log(obj);
每一个函数内部都会有存在这个方法,主要判断一个对象是否为构造函数的实例(即是instanceof)
function User() {}
const Mike = new User
console.log(Mike instanceof User) // true
// 使用函数内部的方法
console.log(User[Symbol.hasInstance](Mike)) // true
// 取自MDN
class Array1 {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([] instanceof Array1);
// expected output: true
以下取自MDN:
内置的方法的参数时是否展开其数组元素。
Symbol.isConcatSpreadable
`符号用于配置某对象作为Array.prototype.concat
let foo = ['a', 'b', 'c']
let = numeric = [1, 2, 3];
let fooAndNumericA = foo.concat(numeric);
console.log(fooAndNumericA); // 结果: ['a', 'b', 'c', 1, 2, 3]
//
numeric[Symbol.isConcatSpreadable] = false;
let fooAndNumericB = foo.concat(numeric)
console.log(fooAndNumericB);
对象的内置属性,一个对象可以被转换成原始值都是靠他帮忙
该函数被调用时,会被传递hint参数,代表预期想要转换的类型
参数的值有三种
- number
- string
- default
number mode:
- 首先调用
valueOf
,若是原始类型,那就返回。- 若非原始值,那麽就调用
toString
,如果是原始类型,那就返回- 如果都不存在,那麽就报错
string mode 在字符串的情况下,行为略有不同(优先级从高到低)
- 首先调用
toString
,如果是原始值,那麽就返回- 如果前面不是原始值,那麽就尝试调用
valueOf
,如果是原始值,那麽就返回- 抛出错误
此例子可以观察Symbol.toPrimitive是如何干扰对象转换成原始类型
// 以下改写自MDN
// 没有改写 Symbol.toPrimitive 的对象
var fooA = {};
console.log(fooA / 1); // NaN
console.log(String(fooA)); // "[object Object]"
console.log(fooA + ""); // "[object Object]"
// 声明一个新的对象,并更改了他的 Symbol.toPrimitive 属性
var fooB = {
[Symbol.toPrimitive](hint) {
if (hint == "number") {
return 'number';
}
if (hint == "string") {
return "string";
}
return 'default';
}
};
console.log(fooB / 1); // Nan
console.log(String(fooB)); // string
console.log(fooB + ""); // default
<<: Day 25 [模块化] 前端模块化:CommonJS,AMD,CMD,ES6
>>: Day 27 [其他05] 前端必知必会--操作URL的黑科技
第12届铁人完赛! 说真实的,原本规划的30天内容大概到第20天就用光了xD 後面10天几乎都是当天...
DAY25 用 Azure Machine Learning SDK 注册模型与部署 之前提过在 A...
案例说明及适用场景 即然都以全WEB了,当然一定会有签核的需求 Base Tier Validati...
题目 给一个型别为string的boolean expression,回传结果(true or fa...
今年的疫情蛮严重的,希望大家都过得安好,希望疫情快点过去,能回到一些线下技术聚会的时光~ 今天要接触...