原始类型:
原始类型 | Undefined | Null | String | Boolean | Number | Symbol |
---|---|---|---|---|---|---|
值 | undefined | null | 所有字符串 | true / false | 所有数字/NaN | symbol |
function show (){
console.log( typeof undefined) // undefined
console.log( typeof 2) //Number
console.log( typeof "asd") // String
console.log( typeof true)
console.log( typeof null)
/**
也许有人会问,在typeOf 的时候,为什么null,会是Object?
这其中是有历史原因的存在的,这实际上是JavaScript当时实现时的一个错误
但是被ECMAScript沿用了。
现在null,被认为是对象的占位符,从而解释了这一个矛盾
但是,从技术的角度出发,它依旧是一个原始值。
*/
console.log( typeof new Number("2"))
console.log( typeof new String(2))
console.log( typeof new Boolean(2))
}
show()
"symbol" 是ES6,新扩展的原始类型;
Symbol,表示独一无二的值。Symbol 值通过Symbol函数生成。
let s = Symbol();
typeOf s
// "symbol"
特性和使用:
1.每个symbol都是独一无二的值。
2.不能使用new关键字。
3.Symbol函数可以接受一个字符串作为参数,表示对Symbol的描述。
let s1 = Symbol('a');
let s2 = Symbol('b');
s1 // Symbol(a)
s2 // Symbol(b)
s1.toString() // "Symbol(a)"
s2.toString() // "Symbol(b)"
4.Symbol函数如果传入一个对象,会被调用toString方法,将对象转为字符串,然后才生成Symbol值。
const obj = {
toString() {
return 'a';
}
};
const sym = Symbol(obj);
sym // Symbol(a)
5.永不相等,多个Symbol函数传入的字符串,即使是一样的,也不会相等。
// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();
s1 === s2 // false
// 有参数的情况
let s1 = Symbol('a');
let s2 = Symbol('a');
s1 === s2 // false
6.不能与其他类型的值进行运算,会报错。
let sym = Symbol('My Symbol');
" Your and" + sym
// TypeError: can't convert symbol to string
` Your and ${sym}`
// TypeError: can't convert symbol to string
Number(sym) // TypeError
sym + 2 // TypeError
//Symbol值可以转为String。
Srting(sym) // 'Symbol(My Symbol)'
sym.toSrting() // 'Symbol(My Symbol)'
//Symbol可以转Boolean值
Boolean(sym) //true;
!sym //false;
if(sym){
// ....
}
引用数据类型:
Object的成员叫做对象,包括Array,Date,RegExp,Math,JSON,Function,等除了原始值外的所有成员。
基本包装类型
JavaScript 提供了三个特殊的引用类型:Boolean,Number,String。
在W3C文档中的解释是,Boolean,Number,String,是各自原始类型的引用类型。
也就是说,包装类型也是引用类型的一种,是对原始类型的封装,封装之后,既会拥有原始类型的功能,也有各自的特殊行为(方法)。
思考一下,我们能不能操作这种封装过实例?
var s1 = 'some text';
s1.color = 'red';
alert(s1.color);//undefined
似乎,行不通。为什么呢? 原来,这种特殊的包装类型,也是有分隐式和显式创建的。
在我们平时操作字符串的时候,所调用的方法
var s1 = 'some text';
var s2 = s1.substring(2);
//可以将以下三个步骤想象成是执行了下列ECMAScript代码。
var s1 = new String('some text'); //(1)创建String类型的一个实例
var s2 = s1.substring(2); //(2)在实例上调用指定的方法
s1 = null; //(3)销毁这个实例
每当读取到一个基本类型值的时候,后台就会自动创建一个相对应的,基本包装类型的对象,从而可以合理的调用某些方法。
这种自动创建的基本包装类型的对象,只存在于执行该代码的那一瞬间,然后即刻被销毁掉。这就是为什么,我们不能直接操作基本包装类型的实例了。
如果想要操作包装类型的实例,当然也是可以的。就是显示的创建,使用new关键字。
var s1 = new String('some text');
s1.color = 'red';
alert(s1.color);//red
在这种情况下的包装类型,就会显得更加接近普通的引用类型了。
valueOf / toString (隐式转换)
Objec调用所得:
String调用所得:
Array调用所得:
Number调用所得:
Date调用所得:
Boolean 调用所得:
Function 调用所得:
Object | String | Array | Number | Date | Boolean | Function | |
---|---|---|---|---|---|---|---|
valueOf | 原始值 | 原始值 | 原始值 | 原始值 | 时间毫秒戳 | 原始值 | 函数类型字符输出 |
toString | [object object] | 原始值 | join方法返回值 | 数字的字符串 | 本地时间字符串 | true/false 字符串 | 字符串函数 |