symbol — это тип из es6, и он тоже относится к категории примитивных типов (string, number, boolean, null, undefined, symbol)
basic
let name = Symbol('xiaohesong')
typeof name // 'symbol'
let obj = {}
obj[name] = 'xhs'
console.log(obj[name]) //xhs
symbol for
Эта штука является разделяемой.При создании она проверяет, найден ли символ этого ключа глобально.Если он существует, то возвращает символ напрямую.Если он не существует, то он будет создан и зарегистрирован глобально.
let uid = Symbol.for("uid");
let object = {
[uid]: "12345"
};
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"
let uid2 = Symbol.for("uid");
console.log(uid === uid2); // true
console.log(object[uid2]); // "12345"
console.log(uid2); // "Symbol(uid)"
Упомянутый здесь общий доступ — это глобальный общий доступ, аналогичный глобальному масштабу, который представляет собой общий доступ во всей среде.
symbol keyfor
let uid = Symbol.for("uid");
console.log(Symbol.keyFor(uid)); // "uid"
let uid2 = Symbol.for("uid");
console.log(Symbol.keyFor(uid2)); // "uid"
let uid3 = Symbol("uid");
console.log(Symbol.keyFor(uid3)); // undefined
В глобальном реестре нет разделяемого символа uid3.Поэтому соответствующий ключ не может быть получен.Видно,что это для получения соответствующего ключа.
Символ не придерживается
let uid = Symbol('uid')
uid + ''
Тут будет ошибка.По спецификации он сконвертирует uid в строку и добавит. Если это действительно складывается, вы можете сначалаString(uid)
Добавьте их позже, но пока это не имеет смысла.
Получение символьного ключа в obj
let uid = Symbol('uid')
let obj = {
[uid]: 'uid'
}
console.log(Object.keys(obj)) // []
console.log(Object.getOwnPropertyNames(obj)) // []
console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(uid)]
Для этого es6 добавилObject.getOwnPropertySymbols
метод.
Считаете ли вы, что символы редко используются?На самом деле их все еще много в es6.
Symbol.hasInstance
У каждой функции есть этот метод. Может быть, вы не очень знакомы с этим методом, он на самом делеinstanceof
дела сделаны.
Да, es6 переопределяет этот метод для вас.
function Xiao(){}
const xiao = new Xiao
xiao instanceof Xiao // true
На самом деле es6 сделал это за вас
Xiao[Symbol.hasInstance](xiao)
Это внутренний метод и не поддерживает переопределение, конечно, мы можем переопределить его на прототипе.
Object.definePrototype(Xiao, Symbol.hasInstance, {
value: (v) => Boolean(v)
})
const x = new Xiao
x instanceof Xiao //true
0 instanceof Xiao //false
1 instanceof Xiao //true
Можно обнаружить, что мы переписываем его, чтобы возвращать, является ли соответствующий тип логическим.
Symbol.isConcatSpreadable
Это отличается от некоторых других свойств, его нет на некоторых стандартных объектах по умолчанию. простой в использовании
let objs = {0: 'first', 1: 'second', length: 2, [Symbol.isConcatSpreadable]: true}
['arrs'].concat(objs) //["arrs", "first", "second"]
Symbol.toPrimitive
Это используется больше.При выполнении преобразования типа объект попытается преобразовать в исходный тип, который черезtoPrimitive
Этот метод существует прототип стандартных типов.
При преобразовании типовtoPrimitive
будет вынужден вызывать с параметром, который в спецификации называетсяhint
, Этот параметр имеет одно из трех значений («число», «строка», «по умолчанию»).
Как подсказывает название,string
то, что возвращаетсяstring
, number
то, что возвращаетсяnumber
,default
не указано, по умолчанию.
Итак, каков случай по умолчанию? В большинстве случаев по умолчанию используется числовой режим. (кроме даты, которая по умолчанию рассматривается как строковый шаблон)
На самом деле вызовов регистра по умолчанию при преобразовании типов не так много. Такие как(==
, +
) или передать параметры вDate
при построении параметров.
-
числовой режим Поведение в случае чисел (приоритет от большего к меньшему)
- первый звонок
valueOf
, если это примитивный тип, верните его. - Если предыдущее значение не является примитивным, попробуйте вызвать
toString
, если это исходное значение, то вернуть - Если ни того, ни другого не существует, сообщите об ошибке
- первый звонок
-
строковый режим В случае строк поведение немного отличается (приоритет меняется от высокого к низкому).
- первый звонок
toString
, если это исходное значение, то вернуть - Если предыдущее значение не является примитивным, попробуйте вызвать
valueOf
, если это исходное значение, то вернуть - бросить ошибку
- первый звонок
Ну, не кажется ли это довольно запутанным, да, давайте объясним код.
let obj = {
valueOf: function(){console.log('valueOf')},
toString: function(){console.log('toString')}
}
// console.log value is
obj + 2 //valueOf
obj == 2 // valueOf
Number(obj) // valueOf
String(obj) // toString
Из вышеприведенного вывода видно, что в большинстве случаев сначала вызываютсяvalueOf
.
Включая случай по умолчанию, его по умолчанию называется цифровой режим, и большинство из них называются цифровыми режимами, вы можете найтиtoString
называетсяstring
режим. Таким образом, вы можете думать, что это в основном числовой режим, если только не отображается строковый режим.
Все еще не очень ясно о шаблоне этого звонка? Ничего страшного, es6 выставляет этот внутренний метод во внешний мир, мы можем переписать его и вывести вот этоhint
тип. Приходить
function Temperature(degrees) {
this.degrees = degrees;
}
Temperature.prototype[Symbol.toPrimitive] = function(hint) {
console.log('hint is', hint)
};
let freezing = new Temperature(32);
freezing + 2 // ..
freezing / 2 // ..
...
Вы можете попробовать вышеперечисленные типы.
Symbo.species
С этим нужно связатьсяclass
в контекстекликните сюдаПосмотреть детали
Symbol.iterator
Это также имеет подробную запись, которая дает некоторые возможности. Для получения подробной информации, пожалуйстаиди сюда
эта статьяоригинальный текст здесь, рекомендую высокое качествоУчебный видео-сайт, много бесплатных видео и ресурсов