JS的内置数据类型罗列以下:segmentfault
undefined null bool number string function object Function Date Error 自定义function new Function new Date new Error new 自定义function symbol
bool, number, string这三种类型的赋值是同相似的。函数
var b = true; var n = 10; var s = 'hello';
与字面量方式等价的函数式赋值:this
var b = Boolean(true); var n = Number(10); var s = String('hello');
可验证变量的类型:prototype
typeof b; // 'bool' typeof n; // 'number' typeof s; // 'string'
假若透过基本类型包装类构造,那么这些变量都变成object类型了。code
var obj_b = new Boolean(true); var obj_n = new Number(10); var obj_s = new String('hello'); typeof obj_b; // 'object' typeof obj_n; // 'object' typeof obj_s; // 'object'
基本类型包装类实例(obj_b, obj_n, obj_s)可认为是基本类型字面量(b, n, s),由值类型被封装成了一个引用类型,两者之间能够作比较的。对象
obj_b.valueOf() == b //true obj_n.valueOf() == n //true obj_s.valueOf() == s //true
看来基本类型包装类(Number, Boolean, String)即能当函数直接调用,也能作构造方法,这正是JS函数的魔法。这里自定义一个函数MyNumber, 模仿Number的实现。继承
function MyNumber(value) { var _self = this; // 若是是new构造出来的 if (_self instanceof MyNumber) { _self.value = value; return _self; } return parseFloat(value); } MyNumber.prototype.valueOf = function() { return parseFloat(this.value); } MyNumber.prototype.doubledValue = function() { return this.valueOf() * 2; } var mnum = MyNumber('12abc'); console.log(mnum); // 12 console.log(typeof mnum);// number var obj_mnum = new MyNumber('12abc'); console.log(obj_mnum); // { [Number: 12] value: '12abc' } console.log(+obj_mnum); // 12. +用来转化为number类型,因此返回.valueOf()的结果 console.log(typeof obj_mnum); // object console.log(obj_mnum.doubledValue()) //24
若不用new,也可用Object.create(..prototype),两者等价。ip
var obj_mnum = Object.create(MyNumber.prototype); MyNumber.call(obj_mnum, '12abc') console.log(obj_mnum); // { [Number: 12] value: '12abc' } console.log(+obj_mnum); // 12. +用来转化为number类型,因此返回.valueOf()的结果 console.log(typeof obj_mnum); // object console.log(obj_mnum.doubledValue()) //24
两者之间能够作算数运算:get
obj_n + n //20 // 过程: obj_n是引用类型 // ->经过调用其valueOf()转为值类型10 // -> 10 + 10 = 20 obj_b + obj_n // 11 // 过程:obj_b引用类型 // -> 调用valueOf()转为值类型true // -> 布尔true须要转为number类型作算数运算,调用Number(true),获得1 // obj_n引用类型 -> 转为值类型 10 // 因此 1 + 10 = 11
关于JS数据类型转换详情,请看Javascript中的类型转换原型
严格来说,基本类型字面量是不能调用任何方法的。可是'hello'.length会成功返回5. 这由于JS解释器在执行这句代码时,会生成一个临时的基本类型包装类的实例,并调用其length。执行完后,就销毁了这个临时变量。
var tmp = new String('hello'); tmp.length
变量声明而不赋值,其值就是undefined
var a; a === undefined; //true. a 严格等于 undefined typeof a; // 'undefined'
若赋值为null:
var a = null; a === null; // true a === undefined; // false, a 再也不严格等于undefined typeof a; // 'object'
可理解为,null是有值的,特殊的空值;而undfined是表示无值。
1.. JSON.stringify会序列化null值,但不会序列化undefined
var obj = {name: 'tom', age: null} JSON.stringify(obj) // '{"name":"tom","age":null}' var obj = {name: 'tom', age: undefined} //'{"name":"tom"}'
对象实例的字段声明为undefined,是无心义的。
2.. undefined会触发ES6的default value,而null不会。
function greet(name='world') { console.log('hello', name) } greet() //hello world greet(undefined) //hello world greet(null) //hello null
这里也进一步印证了, null自己是有值的,不过是个特殊的空值。而undefined是无值的。
值得一提的是,基本类型undefined/null是没有任何方法的,也不可以调用其任何方法。这根bool/number/string不一样,这由于是undefined/null没有包装类
ES6新增的基本类型,只支持函数式赋值,不支持字面量和函数构造。
var sim = Symbol('IBM') // ok sim // Symbol('IBM') typeof sim // 'symbol' sim = new Symbol('IBM') // TypeError: Symbol is not a constructor
JS函数能够经过new Function构造,但一般用function关键字定义。两者的关联,已在独家解析Javascript原型继承 - 之函数原型和AOP有详细的阐述。这里就简要说明下,函数自己和函数构造实例的一点区别。
type of Date // function. Date自己是函数 typeof new Date() // object. 经过new Date构造出来的是object实例 new Date().__proto__ == Date.prototype //true. // new Date()既然是由Date函数构造出来的, // 因此new Date()的run-time __proto__就是Date的design-time的prototype // new Date()就是Date的构造实例了 new Date() instanceof Date // true.
关于 run-time __proto__和design-time prototype,请读者参考独家解析Javascript原型继承