• 03标准对象-01-Date和JSON


    0、写在前面的话

    在JS世界中,一切都是对象,区别对象类型使用tyepof,返回一个字符串,如:
    typeof 123; // 'number' 
    typeof NaN; // 'number'
    typeof 'str'; // 'string'
    typeof true; // 'boolean'
    typeof undefined; // 'undefined'
    typeof Math.abs; // 'function'
    typeof null; // 'object'
    typeof []; // 'object'
    typeof {}; // 'object'

    和Java类似,JS中也提供了包装对象,使用new创建,变成Object后同Java中类似,直接使用===对比会返回false:
    var n = new Number(123); // 123,生成了新的包装类型
    var b = new Boolean(true); // true,生成了新的包装类型
    var s = new String('str'); // 'str',生成了新的包装类型

    不写new,直接使用 Number() 诸如此类,是强转类型的函数:
    var n = Number('123'); // 123,相当于parseInt()或parseFloat()
    typeof n; // 'number'
    
    var b = Boolean('true'); // true
    typeof b; // 'boolean'
    
    var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串!
    var b3 = Boolean(''); // false
    
    var s = String(123.45); // '123.45'
    typeof s; // 'string'

    总结一下规则
    • 不要使用new Number()、new Boolean()、new String()创建包装对象
      • 包装对象创建/实例化出来的,是对象类型,而不是Number/Boolean/String类型

    • 类型转换
      • 用parseInt()或parseFloat()来转换任意类型到number
      • 用String()来转换任意类型到string,或者直接调用某个对象的toString()方法

    • 类型判断
      • 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...}
      • typeof操作符可以判断出number、boolean、string、function和undefined
      • 判断Array要使用Array.isArray(arr)
      • 判断null请使用myVar === null

    • 判断存在性
      • 判断某个全局变量是否存在用typeof window.myVar === 'undefined'
      • 函数内部判断某个变量是否存在用typeof myVar === 'undefined'

    • 其他
      • null 和 undefined 没有toString()方法
      • number对象调用toString()会报错,需要处理一下: 123.toString() //SyntaxError   (123).toString(); // '123'


    1、Date

    多说无意,看代码:
    var now = new Date();
    now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
    now.getFullYear(); // 2015, 年份
    now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
    now.getDate(); // 24, 表示24号
    now.getDay(); // 3, 表示星期三
    now.getHours(); // 19, 24小时制
    now.getMinutes(); // 49, 分钟
    now.getSeconds(); // 22, 秒
    now.getMilliseconds(); // 875, 毫秒数
    now.getTime(); // 1435146562875, 以number形式表示的时间戳

    注意:该时间是从本机操作系统获取的时间,如果用户将当前时间设定为其他的值,那么获取的时间也是不同的。

    Date对象表示的时间总是按浏览器所在的时区显示的,可以通过方法显示本地时间,或调整后的UTC时间:
    var d = new Date(1435146562875);
    d.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
    d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间,与本地时间相差8小时

    这里传递的参数实际上是一个number类型的时间戳,之前我们的示例代码中提到过,一个Date对象使用getTime方法可以得到number形式的时间戳。

    *时间戳:从1970年1月1日零时整的GMT时区开始,到现在此刻的毫秒数,是一个自增的整数。


    2、JSON

    其实把JSON和之前的Date放在同一个博文里似乎有些不合适,Date确实是一个对象,但是JSON实际上说来是一种数据格式。不过,先这样吧,谁让我懒呢。

    另,之前关于JSON专门写过一篇入门小博文,可以戳下再了解下:《JSON的基本结构和数据交换原理

    简单说来,JSON就是一种轻量级的数据交换格式,比XML轻量很多,发明这个格式的人钟情于JavaScript,所以设计的JSON实际上就是JavaScript的子集,所以JS中可以直接使用JSON,因为JS中内置了JSON的解析。

    也因如此,JSON作为一种数据交换格式,其定义的数据类型也就跟JS基本一样
    • number
    • boolean
    • string
    • array
    • object
    • null

    JSON还定死了字符集必须是UTF-8。为统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""。

    最后:
    • JS对象变成JSON,就是把这个对象序列化成JSON格式的字符串,就能够通过网络传递到其他计算机
    • 收到JSON格式字符串,只需要反序列化成为JS对象,就可以在JavaScript中直接使用这个对象了

    2.1 序列化 JSON.stringify()

    假如有一个小明对象,我们要将这个对象序列化成JSON格式的字符串:
    var xiaoming = {
        name: '小明',
        age: 14,
        gender: true,
        height: 1.65,
        grade: null,
        'middle-school': '"W3C" Middle School',
        skills: ['JavaScript', 'Java', 'Python', 'Lisp']
    };
    
    JSON.stringify(xiaoming); 
    //'{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":""W3C" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'

    为了输出好看些,可以加上参数,按缩进输出:
    JSON.stringify(xiaoming, null, '  ');
    
    //结果
    {
      "name": "小明",
      "age": 14,
      "gender": true,
      "height": 1.65,
      "grade": null,
      "middle-school": ""W3C" Middle School",
      "skills": [
        "JavaScript",
        "Java",
        "Python",
        "Lisp"
      ]
    }

    第二个参数用于控制如何筛选对象的键值,如果只想输出指定的属性,可以传入Array
    JSON.stringify(xiaoming, ['name', 'skills'], '  ');
    
    //结果
    {
      "name": "小明",
      "skills": [
        "JavaScript",
        "Java",
        "Python",
        "Lisp"
      ]
    }

    第二个参数还可以传入函数,这样每个键值对都会被函数先处理
    function convert(key, value) {
        if (typeof value === 'string') {
            return value.toUpperCase();
        }
        return value;
    }
    
    JSON.stringify(xiaoming, convert, '  ');
    
    //结果:把所有属性值变成大写
    {
      "name": "小明",
      "age": 14,
      "gender": true,
      "height": 1.65,
      "grade": null,
      "middle-school": ""W3C" MIDDLE SCHOOL",
      "skills": [
        "JAVASCRIPT",
        "JAVA",
        "PYTHON",
        "LISP"
      ]
    }

    如果我们还想要精确控制如何序列化小明,可以给xiaoming定义一个toJSON()的方法,直接返回JSON应该序列化的数据:
    var xiaoming = {
        name: '小明',
        age: 14,
        gender: true,
        height: 1.65,
        grade: null,
        'middle-school': '"W3C" Middle School',
        skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
        toJSON: function () {
            return { // 只输出name和age,并且改变了key:
                'Name': this.name,
                'Age': this.age
            };
        }
    };
    
    JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'

    2.2 反序列化

    拿到一个JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象
    JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
    JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
    JSON.parse('true'); // true
    JSON.parse('123.45'); // 123.45

    序列化中我们可以对方法增加函数,进行预处理,同理,在反序列化中,我们也可以让JSON.parse()接收一个函数,用来转换解析出的属性
    JSON.parse('{"name":"小明","age":14}', function (key, value) {
        // 把number * 2:
        if (key === 'name') {
            return value + '同学';
        }
        return value;
    }); // Object {name: '小明同学', age: 14}

    实际上,还有第二种方式可以将JSON格式的字符串转换为JS对象,使用eval函数:
    eval(string);
    //eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码

    可能有人要疑惑,为什么JSON格式的字符串,可以计算执行成为一个JS对象呢?因为JSON格式的字符串其实可以说是一种 “对象字面量”,执行这个字符串自然也就对应生成了对象。值得注意的是,为了避免JSON中花括号被当成语句块处理,我们在使用eval方法时,要对JSON格式的字符串加上括号。

    所以,JSON.parse(jsonStr)的方式,也可以写成下面格式:
    var xiaoming = '{"name":"小明", "age":14}';
    var jsObj = eval("(" + xiaoming + ")");

    *字面量:由语法表达式定义的常量,或你可以理解为,是通过由一定字词组成的语词表达式定义的常量


  • 相关阅读:
    Html语言基础
    acm练习(四)
    acm练习(三)
    acm练习(二)
    acm练习(一)
    android自定义控件属性
    android ViewGroup getChildDrawingOrder与 isChildrenDrawingOrderEnabled()
    java 用Arrays.binarySearch解读 快速定位数字范围
    android极光推送初步了解...
    GridView与ListView冲突
  • 原文地址:https://www.cnblogs.com/deng-cc/p/6623606.html
Copyright © 2020-2023  润新知