javascript中原始值,即基本数据类型,像Number,String,Boolean,undefined,Null都是基本类型值,保存在栈中,但是有个疑问:

Symbol打印出来明明是个函数,具有prototype的属性,不能实例化的原因是:Symbol是个原始值。但Symbol明明就是个函数的鸭,而且:

Symbol.__proto__ === Function.prototype     //true
Symbol.constructor === Function.prototype.constructor //true
Object.prototype.toString.call(Symbol) //"[object Function]"
typeof Symbol //"function"
typeof Symbol() //"symbol"

Symbol的原型指向的就是Function的原型,Symbol明明就是Function的实例鸭。

其实JS中检测原始值的方法就是用typeof,那么typeof Symbol返回的就是function类型。typeof Symbol(),好嘛!!!返回symbol类型。

在Javascript中函数即对象,是引用类型,为啥Symbol就是原始值,即基本类型呢?

好吧!阮一峰这里有解释说:

Symbol 值是原始类型,Symbol() 构造函数是对象。

Question:我们知道Number,Array,String,Boolean,Object都是可以进行实例化对象操作的,就是使用new操作符,思考下,number,string,boolean也是基本类型,为何就可以使用new,而Symbol()就不行呢?

解释下:symbol类型只能通过Symbol()函数的调用创建。symbol是基本类型,而Symbol()构造函数是个对象,既然是个构造器,为何就不能通过new操作符来实现一个实例化对象呢?

这里提及下Javascript的包装对象,有三种就是Boolean,Number,String。显示的创建包装对象是可以的,利用new Boolean()等方法,但是Symbol()函数对象内部阻止你显示创建一个symbol包装对象,所以你不能用new来创建一个symbol对象。只能通过Symbol("s")来创建一个基本数据类型——symbol类型。

如果你想创建一个Symbol包装对象,那么你可以先创建一个symbol基本类型值,然后通过Object()方法得到Symbol对象。"

敲黑板:

1,看栗子:

var s1 = 'abc'
var s2 = 'abc'
console.log(s1 === s2) //true
var sym1 = Symbol('abc')
var sym2 = Symbol('abc')
console.log(sym1 === sym2) //false
  console.log(Symbol.for('foo') === Symbol.for('foo'));//true

但是Symbol.for(key)方法返回一个全局的Symbol变量,不会每次都创建新的symbol,而是返回之前已经创建的symbol。这不就是单例模式嘛!

Symbol.keyFor(sym)方法返回定义symbol类型时传入的key字符串,如果没传入则为undefined。

Object.getOwnPropertySymbols(obj):返回一个数组,数组成员是对象的所有属性名为Symbol值。

const object1 = {};
const a = Symbol('a');
const b = Symbol.for('b'); object1[a] = 'localSymbol';
object1[b] = 'globalSymbol'; const objectSymbols = Object.getOwnPropertySymbols(object1);
console.log(objectSymbols)
// [Symbol(a), Symbol(b)]
Reflect.ownKeys(obj)
// [Symbol(a), Symbol(b)]

看阮一峰的文字呢,其实都是他自己的理解,每个人在对知识的理解上面会有些偏差,最好还是看官网吧。上面一段话意思是:Symbol()函数呢,返回一个类型为symbol的值,具有内置对象的静态属性和全局symbol的一些静态方法,类似于一个内置对象类,但是不能当做构造器函数,因为不支持“new Symbol()”语法。

每个symbol都是Symbol()函数返回的,唯一的,可以作为对象的属性名,这是symbol类型存在的唯一目的,其他用处可以去更多了解Symbol。symbol类型是原始值。

let sym = Symbol();

let obj = {
[sym]:"miya"
}
let a = {};
Object.defineProperty(a,sym,{value:'miya'}) console.log(obj[sym]) //miya
console.log(a[sym]) //miya

symbol值作为对象属性名只能通过[sym]来获取,不能通过点运算符。

对象的symbol类型属性名,只能通过Object.getOwnPropertySymbols(obj)获取,通过for...in/of或者其他都是不行的。

let s = Symbol();
let obj = {
[s](args){
console.log(args)
}
}
obj[s]('123') //

上面的例子是:给对象obj里面添加s的属性方法,使用ES6支持的函数的写法,函数名可以使用symbol原始值类型。

阮一峰举了一个使用symbol类型来消除魔术字的例子:

const shapeType = {
triangle:Symbol()
}
function getArea(shape,options){
let area = 0;
switch(shape){
case shapeType.triangle:
area = .5*options.width*options.height;
break;
}
return area;
}
getArea(shapeType.triangle,{width:100,height:100}) //

本来shapeType.triangle是个比较长的字符串,其实字符串是什么并不重要,只要属性值不冲突就行,刚好适合symbol的适用场景。

【完】

这两天都在了解Symbol类型,从最开始的云里雾里,扒了JS的包装对象,涨了些姿势。

最新文章

  1. 轮廓线DP POJ3254 && BZOJ 1087
  2. Stanford机器学习笔记-6. 学习模型的评估和选择
  3. Jquery-input获取单选框选择的按钮
  4. 跟着百度学PHP[3]-PHP中结构嵌套之循环结构与条件结构嵌套
  5. 自定义获取焦点的TextView
  6. Javascript scrollTop 20大洋
  7. 配置Windows Server 2008 允许多用户远程桌面连接
  8. [转]Disabling ASLR on individual iOS applications when using iOS 6.0.1
  9. Callback Promise Generator Async-Await 和异常处理的演进
  10. Java 程序测试_循环语句中的break和continue
  11. jvm参数解析(含调优过程)
  12. Spring事务源码阅读笔记
  13. CentOS7 安装 MySQL
  14. Xcode 添加pch 文件
  15. LeetCode(123):买卖股票的最佳时机 III
  16. PHP自动加载(__autoload和spl_autoload_register)
  17. 生成器-代码举例:()和yield
  18. 关于spark standalone模式下的executor问题
  19. 迷你MVVM框架 avalonjs 1.3.6发布
  20. CentOS 7下配置安装KVM

热门文章

  1. Date类与SimpleDateFormat类中parse()方法和format()方法
  2. 解密优秀博士成长史 ——微软亚洲研究院首届博士生学术论坛Panel讨论经验总结
  3. Docker:发布镜像问题denied: requested access to the resource is denied的解决方法
  4. mysql挖掘与探索------第一章(简介)
  5. Klotski's Blog
  6. @Value默认值填null
  7. vue面试总结
  8. unittest(8)- 学习ddt
  9. ServletContext+ServletConfig内容
  10. 查漏补缺:OSI七层模型和TCP/IP模型