资讯专栏INFORMATION COLUMN

闲话JavaScript数据类型

jerryloveemily / 1554人阅读

摘要:支持的类型的内置数据类型罗列如下自定义自定义这三种类型的赋值是同类似的。这根不同,这因为是没有包装类新增的基本类型,只支持函数式赋值,不支持字面量和函数构造。

JavaScript支持的类型

JS的内置数据类型罗列如下:

undefined
null
bool
number
string
function
object
    Function
        Date
        Error
        自定义function
    new Function
    new Date
    new Error
    new 自定义function
symbol
bool, number, string

bool, number, string这三种类型的赋值是同类似的。

字面量方式赋值
var b = true;
var n = 10;
var s = "hello";
函数式赋值

与字面量方式等价的函数式赋值

var b = Boolean(true);
var n = Number(10);
var s = String("hello");

可验证变量的类型:

typeof b; // "bool"
typeof n; // "number"
typeof s; // "string"
基本类型包装类

倘若透过基本类型包装类构造,那么这些变量都变成object类型了。

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),二者等价。

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
基本类型字面量和基本类型包装类实例的关系

二者之间可以做算数运算:

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 和 null

变量声明而不赋值,其值就是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是表示无值。

undefined 和 null的一些区别

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没有包装类

symbol

ES6新增的基本类型,只支持函数式赋值,不支持字面量和函数构造。

var sim = Symbol("IBM") // ok
sim                     // Symbol("IBM")
typeof sim              // "symbol"
sim = new Symbol("IBM") // TypeError: Symbol is not a constructor
function 和 Function

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原型继承

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84057.html

相关文章

  • 2017-07-17 前端日报

    摘要:前端日报精选听说你没来总结个人使用过的移动端布局方法新特性简介用写组件坦然面对应对前端疲劳中文深入理解笔记函数前端架构经验分享系列教程之创建页面元素龙云全栈系列教程之定位页面元素龙云全栈第期与表单验证技术周刊期知乎 2017-07-17 前端日报 精选 听说你没来 JSConf 2017?总结个人使用过的移动端布局方法 - Rni-L - SegmentFaultNode.js v8....

    caiyongji 评论0 收藏0
  • JavaScript 编程精解 中文第三版 十一、异步编程

    摘要:回调异步编程的一种方法是使执行慢动作的函数接受额外的参数,即回调函数。执行异步工作的函数通常会在完成工作之前返回,安排回调函数在完成时调用。它注册了一个回调函数,当解析并产生一个值时被调用。 来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目原文:Asynchronous Programming 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌...

    GeekQiaQia 评论0 收藏0
  • HTML+CSS+JAVASCRIPT 高仿低配网页版网易云音乐播放器

    摘要:高仿低配网页版网易云音乐播放器前言没有使用任何框架,只是想用最简单纯的代码实现下前台后台是参考网上的例子写的,代码是在的基础上重新写的还有她的姊妹篇网易云音乐移动端,请查看这里写在前头的话鄙人野生前端一只,专业,自学前端已经一年多了 HTML+CSS+JAVASCRIPT 高仿低配网页版网易云音乐播放器 showImg(https://segmentfault.com/img/remo...

    RaoMeng 评论0 收藏0
  • HTML+CSS+JAVASCRIPT 高仿低配网页版网易云音乐播放器

    摘要:高仿低配网页版网易云音乐播放器前言没有使用任何框架,只是想用最简单纯的代码实现下前台后台是参考网上的例子写的,代码是在的基础上重新写的还有她的姊妹篇网易云音乐移动端,请查看这里写在前头的话鄙人野生前端一只,专业,自学前端已经一年多了 HTML+CSS+JAVASCRIPT 高仿低配网页版网易云音乐播放器 showImg(https://segmentfault.com/img/remo...

    sean 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<