面试官:能否说说你对es6中Symbol的理解?

435 阅读3分钟

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

前言

当面试官问出这题时,考虑了面试者对于新知识出现的求知欲,也同时考验了面试者碰到新知识时的理解与概括。

看懂以下的章节,让面试官对你有个满意的理解。

为什么会在新标准里加入Symbol?

在项目中,调用了某个大佬写的对象方法common.getUserName()时,你也想获取对象中的user english name。 于是你在对象上添加了同名方法getUserName,就把原来的方法覆盖掉而产生错误了。

虽然这种情况很极端,对于一个正常的前端工程师而言不会发生这种错误,但是对于程序是严谨的,如果它可能犯错,那必然会犯错。

所以才会诞生了Symbol

Symbol的特性

  1. 相同参数使用Symbol构造出的值都是不相等的。
let a = Symbol('name')
let b = Symbol('name')

a === b // false
  1. Symbol(Element), 当Element为原始类型时,会返回字符串。当Element为对象类型时,会返回Element.toString()
let bool = Symbol(true)
let object = Symbol({name: 'kev1nzh'})
let array = Symbol([1,2,3,4,5])

console.log(bool) // Symbol(true)
console.log(object) // 'Symbol([object Object])'
console.log(array) // 'Symbol(1,2,3,4,5)'

Symbol的运用

  1. 运用于对象中的key。让对象中的变量和方法成为Symbol,保证属性的唯一性。
const studentName = Symbol('name') // Symbol('name') 返回的string
const getStudentName = Symbol('getStudentName') // Symbol('getStudentName') 返回的string

const student = {
    [studentName]: 'kev1nzh',
    [getStudentName]: function () { console.log(this[studentName])}
}

student[getStudentName]() //'kev1nzh'
// 当我在student上新建方法时,也不会覆盖之前的方法。
student[Symbol('getStudentName')] // undefined 
// 当然正常情况下也是先命名新方法的Symbol,再在对象上写新方法。
  1. 要是我们头铁,就是想修改大佬写的getStudentName的方法怎么办?我们看看Symbol.for()
const studentName = Symbol.for('name') // Symbol('name') 返回的string
const getStudentName = Symbol.for('getStudentName') // Symbol('getStudentName') 返回的string

const student = {
    [studentName]: 'kev1nzh',
    [getStudentName]: function () { console.log(this[studentName])}
}

student[Symbol.for('getStudentName')] = () => console.log('marven')
student[getStudentName]() //'marven'

这里我们可以看懂命名变量时的改变,Symbol('name') => Symbol.for('name')

只要记住在使用Symbol.for()创建时,会比直接Symbol()多出一个步骤,那就是先去全局环境中搜寻传入的key,如果在全局环境中存在,那就返回存在的Symbol类型。如果不存在,那就和Symbol()的逻辑一样,创建新的类型并且根据传入类型生成返回值。

需要注意的知识点。

  1. 调用Symbol()时,前面不能加new命令,因为Symbol()返回的是原始类型的数据。
const name = Symbol('kev1nzh')
console.log(typeof name) // Symbol('kev1nzh')
  1. 如何知道对象中的Symbol()方法或变量?
const name = Symbol('name')
const age = Symbol('age')

const student = {
    [name]: 'student',
    [age]: 20
}

const studentParams = Object.getOwnPropertySymbols(student)
console.log(studentParams) // [Symbol(name), Symbol(age)]
  1. Symbol.keyFor(), 如何获取Symbol类型的key
const studentName = Symbol.for('name') 
console.log(Symbol.keyFor(studentName)) // 'name'

最后

打完收工。

面试系列第一篇: 面试官:你知道Callback Hell(回调地狱)吗?

面试系列第二篇: 面试官:react和vue有什么区别吗?

面试系列第三篇: 面试官:你了解es6的知识吗?

面试系列第四篇: 面试官:你了解Webpack吗?

面试系列第五篇: 面试官:你使用webpack时手写过loader,分离过模块吗?

面试系列第六篇: 面试官:如何正确的判断Javascript中的数据类型?

如果您有收获或者疑问请在下方评论,求赞!谢谢观看到这里。