# JSON

    # 对象基本概念

    在 JavaScript 中对象是拥有属性和方法的数据。

    # 属性和方法

    属性是与对象相关的值,也可以理解为特征。方法是能够在对象上执行的动作,也可以理解为行为。

    # JSON

    JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种由道格拉斯·克罗克福特构想和设计、轻量级的数据交换语言,该语言以易于让人阅读的文字为基础,用来传输由属性值或者序列性的值组成的数据对象。尽管 JSON 是 JavaScript 的一个子集,但 JSON 是独立于语言的文本格式,并且采用了类似于 C 语言家族的一些习惯。

    JSON 数据格式与语言无关,脱胎于 JavaScript,但当前很多编程语言都支持 JSON 格式数据的生成和解析。JSON 的官方 MIME 类型是 application/json,文件扩展名是 .json。

    注:定义来自维基百科。

    下面给出两个简单的 json 示例:

    {
      "name": "zhangsan",
      "age": 18,
      "gender": "male"
    }
    {
      "students": [
        { "firstName": "san", "lastName": "zhang" },
        { "firstName": "si", "lastName": "li" },
        { "firstName": "wu", "lastName": "wang" }
      ]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    特别需要注意的是:

    • JSON 是一种纯数据格式,它只包含属性,没有方法。
    • JSON 的属性必须通过双引号引起来。
    • JSON 要求两头有 {} 来使其合法。
    • 可以把 JavaScript 对象原原本本的写入 JSON 数据,比如:字符串,数字,数组,布尔还有其它的字面值对象。

    # 常用内置对象介绍

    前面在我们讲数组的方法和字符串的操作的时候,已经讲解了一部分内置对象的内容。本节,我们再来系统的学习一下一些常用的内置对象。

    # Array 对象

    1. Array 对象的常用属性:length,获取数组的长度。
    2. Array 对象的常用方法:
    • concat() 方法用于连接两个或多个数组,并返回结果。语法为:
    arrayObject.concat(arrayX, arrayX, ..., arrayX);
    
    1

    例子:

    var a = [1, 2, 3];
    var b = [4, 5, 6];
    var c = ["one", "two", "three"];
    console.log(a.concat(b, c)); // 打印结果为:[1, 2, 3, 4, 5, 6, "one", "two", "three"]
    
    1
    2
    3
    4
    • join() 方法,将数组转换成字符串。(数组章节有详细介绍,这里不过多的赘述,下面的类似情况同样处理,大家看到这个方法,首先回想一下我们前面所学的知识,如有遗忘,再回去看一看加深记忆)。
    • pop() 方法,删除并返回数组的最后一个元素。
    • push() 方法,向数组的末尾添加一个或更多元素,并返回新的长度。
    • reverse() 方法,颠倒数组的顺序。比如:
    var a = [1, 2, 3, 4];
    a.reverse();
    console.log(a); // a 数组变成:[4, 3, 2, 1]。
    
    1
    2
    3
    • shift() 方法,删除并返回数组的第一个元素。
    • unshift() 方法,向数组的开头添加一个或更多元素,并返回新的长度。
    • slice() 方法,从某个已有的数组返回选定的元素。语法为:
    arrayObject.slice(start, end);
    // strat 值是必需的,规定从何处开始选取
    // end 值可选,规定从何处结束选取,如果没有设置,默认为从 start 开始选取到数组后面的所有元素
    
    1
    2
    3

    在控制台中输入以下代码:

    var a = [1, 2, 3, 4, 5, 6];
    a.slice(2, 5); // 结果为[3, 4, 5],另外需要注意的是该方法不会修改数组,只是返回一个子数组,a 数组还是 [1, 2, 3, 4, 5, 6]
    
    1
    2
    • splice() 方法,删除或替换当前数组的某些项目。语法为:
    arrayObject.splice(start, deleteCount, options);
    // start 值是必需的,规定删除或替换项目的位置
    // deleteCount 值是必需的,规定要删除的项目数量,如果设置为 0,则不会删除项目
    // options 值是可选的,规定要替换的新项目
    // 和 slice() 方法不同的是 splice() 方法会修改数组
    
    1
    2
    3
    4
    5

    在控制台中输入以下代码:

    var a = [1, 2, 3, 4, 5, 6];
    a.splice(2, 2, "abc");
    a; // 最终 a 数组变成了[1, 2, "abc", 5, 6]
    
    1
    2
    3
    • sort() 方法,将数组进行排序。语法为:
    arrayObject.sort(sortby);
    // sortby 是可选的,规定排序顺序,必需是函数。如果没有参数的话,将会按照字母顺序进行排序,更准确的说是按照字符编码(可自行百度了解)的顺序进行排序。如果想按照其他标准进行排序,则需要提供比较函数
    
    1
    2

    例子:

    <script>
        var arr1 = ["a", "z", "k", "w", "x"];
        document.write(arr1 + "<br />");
        document.write(arr1.sort()+ "<br />" + "<br />");
    
        var arr2 = [11,55,22,44,66,33];
        document.write(arr2 + "<br />");
        document.write(arr2.sort() + "<br />" + "<br />");
    
        var arr3 = [1,22,44,6,55,5,2,4,66];
        document.write(arr3 + "<br />");
        document.write(arr3.sort() + "<br />" + "<br />");
    
        function sortNum1(a, b){
            return a - b; // 从小到大排序
        }
        var arr4 = [1,22,44,6,55,5,2,4,66];
        document.write(arr4 + "<br />");
        document.write(arr4.sort(sortNum1) + "<br />" + "<br />");
    
        function sortNum2(a,b){
            return b - a; // 从大到小排序
        }
        var arr4 = [1,22,44,6,55,5,2,4,66];
        document.write(arr4 + "<br />");
        document.write(arr4.sort(sortNum2) + "<br />" + "<br />");
    </script>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    • toString() 方法,把数组转换为字符串,并返回结果。

    # String 对象

    1. String 对象的常用属性:length,获取字符串的长度。
    2. String 对象的常用方法:
    • charAt() 方法,获取指定位置处字符。语法为:
    stringObject.charAt(index);
    // 字符串中第一个字符的下标是 0。如果参数 index 不在 0 与 string.length 之间,该方法将返回一个空字符串
    
    1
    2

    例子:

    var str = "Hello world!";
    document.write(str.charAt(2));
    // 以上代码输出为 l
    
    1
    2
    3
    • charCodeAt() 方法,获取指定位置处字符的 Unicode 编码。语法为:
    stringObject.charCodeAt(index);
    // 字符串中第一个字符的下标是 0。如果 index 是负数,或大于等于字符串的长度,则 charCodeAt() 返回 NaN
    
    1
    2

    例子:

    var str = "Hello world!";
    document.write(str.charCodeAt(2));
    // 以上代码输出为 l08
    
    1
    2
    3
    • concat() 方法,连接字符串,等效于 “+”,“+” 更常用。与数组中的 concat() 方法相似。
    • slice() 方法,提取字符串的片断,并在新的字符串中返回被提取的部分(字符串章节有详细介绍,这里不过多的赘述,下面的类似情况同样处理)。
    • indexOf() 方法,检索字符串。
    • toString() 方法,返回字符串。
    • toLowerCase() 方法,把字符串转换为小写。
    • toUpperCase() 方法,把字符串转换为大写。
    • replace() 方法,替换字符串中的某部分。
    • split() 方法,把字符串分割为字符串数组。

    # Date 对象

    Date 对象方法:

    • Date():返回当日的日期和时间(输出的是中国标准时间)。
    • getDate():从 Date 对象返回一个月中的某一天 (1 ~ 31)。
    • getDay():从 Date 对象返回一周中的某一天 (0 ~ 6)。
    • getMonth():从 Date 对象返回月份 (0 ~ 11)。
    • getFullYear():从 Date 对象以四位数字返回年份。
    • getHours():返回 Date 对象的小时 (0 ~ 23)。
    • getMinutes():返回 Date 对象的分钟 (0 ~ 59)。
    • getSeconds():返回 Date 对象的秒数 (0 ~ 59)。
    • getMilliseconds():返回 Date 对象的毫秒(0 ~ 999)。

    # Math 对象

    1. Math 对象的常用属性:
    • E :返回常数 e (2.718281828...)。
    • LN2 :返回 2 的自然对数 (ln 2)。
    • LN10 :返回 10 的自然对数 (ln 10)。
    • LOG2E :返回以 2 为底的 e 的对数 (log2e)。
    • LOG10E :返回以 10 为底的 e 的对数 (log10e)。
    • PI :返回 π(3.1415926535...)。
    • SQRT1_2 :返回 1/2 的平方根。
    • SQRT2 :返回 2 的平方根。
    1. Math 对象的常用方法:
    • abs(x) :返回 x 的绝对值。
    • round(x) :返回 x 四舍五入后的值。
    • sqrt(x) :返回 x 的平方根。
    • ceil(x) :返回大于等于 x 的最小整数。
    • floor(x) :返回小于等于 x 的最大整数。
    • sin(x) :返回 x 的正弦。
    • cos(x) :返回 x 的余弦。
    • tan(x) :返回 x 的正切。
    • acos(x) :返回 x 的反余弦值(余弦值等于 x 的角度),用弧度表示。
    • asin(x) :返回 x 的反正弦值。
    • atan(x) :返回 x 的反正切值。
    • exp(x) :返回 e 的 x 次幂 (e^x)。
    • pow(n, m) :返回 n 的 m 次幂 (nm)。
    • log(x) :返回 x 的自然对数 (ln x)。
    • max(a, b) :返回 a, b 中较大的数。
    • min(a, b) :返回 a, b 中较小的数。
    • random() :返回大于 0 小于 1 的一个随机数。

    # 创建对象和访问对象

    创建对象的方式有很多,下面为大家讲解几种常用的方式。

    # 通过对象字面量来创建

    var student = {
      name: "zhangsan",
      age: 18,
      gender: "male",
      sayHi: function () {
        console.log("hi,my name is " + this.name);
      },
    };
    
    1
    2
    3
    4
    5
    6
    7
    8

    把上面的代码复制到控制台中,然后尝试依次输入下面的代码看看效果:

    student.name;
    student.age;
    student.gender; // 调用对象的属性
    student.sayHi(); // 调用对象的方法
    
    1
    2
    3
    4

    通过上面的例子你会发现对象的属性和方法通过 "." 来访问。

    # 通过 new Object() 创建对象

    var student = new Object();
    (student.name = "zhangsan"),
      (student.age = 18),
      (student.gender = "male"),
      (student.sayHi = function () {
        console.log("hi,my name is " + this.name);
      });
    
    1
    2
    3
    4
    5
    6
    7

    # 通过工厂函数创建对象

    function createStudent(name, age, gender) {
      var student = new Object();
      student.name = name;
      student.age = age;
      student.gender = gender;
      student.sayHi = function () {
        console.log("hi,my name is " + this.name);
      };
      return student;
    }
    var s1 = createStudent("zhangsan", 18, "male");
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 自定义构造函数

    function Student(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
      this.sayHi = function () {
        console.log("hi,my name is " + this.name);
      };
    }
    var s1 = new Student("zhangsan", 18, "male");
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # new 关键字

    构造函数,是一种特殊的函数。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总与 new 运算符一起使用在创建对象的语句中。这里有需要特别注意的几点:

    • 构造函数用于创建一类对象,首字母要大写。
    • 内部使用 this 关键字给对象添加成员。
    • 使用 new 关键字调用对象构造函数。

    # this 详解

    在 JavaScript 中,我们经常会使用到 this 关键字,那么 this 到底指向什么呢?这里有一个口诀:谁调用 this,它就是谁。大家也可以从前面的例子中细细体会一下。

    • 函数在定义的时候 this 是不确定的,只有在调用的时候才可以确定。
    • 一般函数直接执行,内部 this 指向全局 window。比如:
    function test() {
      console.log(this);
    }
    test(); // window.test();
    
    1
    2
    3
    4
    • 函数作为一个对象的方法,被该对象所调用,那么 this 指向的是该对象。
    • 构造函数中的 this,始终是 new 的当前对象。

    # 遍历对象的属性

    通过 for...in 语句用于遍历数组或者对象的属性,对数组或者对象的属性进行循环操作。比如:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title></title>
      </head>
    
      <body>
        <script>
          var student = {
            name: "zhangsan",
            age: 18,
            gender: "male",
          };
          for (var key in student) {
            console.log(key);
            console.log(student[key]);
          }
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    注:key 是一个变量,这个变量中存储的是该对象的所有的属性的名字。

    # 删除对象的属性

    使用 delete 删除对象的属性。比如在控制台中输入以下代码:

    var student = {
      name: "zhangsan",
      age: 18,
      gender: "male",
    };
    student.name; // zhangsan
    delete student.name;
    student.name; // undefined
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 案例

    1. 写一个函数,格式化日期对象,最终输入形式为:yyyy/MM/dd HH:mm:ss。比如:

    1

    参考源码:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title></title>
      </head>
    
      <body>
        <script>
          function formatDate(d) {
            // 如果 d 不是日期对象的实例,返回空
            if (!d instanceof Date) {
              return;
            }
            var year = d.getFullYear(),
              month = d.getMonth() + 1,
              date = d.getDate(),
              hour = d.getHours(),
              minute = d.getMinutes(),
              second = d.getSeconds();
            month = month < 10 ? "0" + month : month;
            date = date < 10 ? "0" + date : date;
            hour = hour < 10 ? "0" + hour : hour;
            minute = minute < 10 ? "0" + minute : minute;
            second = second < 10 ? "0" + second : second;
            return (
              year +
              "/" +
              month +
              "/" +
              date +
              " " +
              hour +
              ":" +
              minute +
              ":" +
              second
            );
          }
          console.log(formatDate(new Date()));
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    1. 写一个函数去掉数组中的重复元素。比如有一个数组 array = ["x", "c", "a", "b", "c", "b", "c"]。

    参考源码:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title></title>
      </head>
    
      <body>
        <script type="text/javascript">
          var array = ["x", "c", "a", "b", "c", "b", "c"];
    
          function clearArray() {
            var o = {};
            for (var i = 0; i < array.length; i++) {
              var item = array[i];
              if (o[item]) {
                o[item]++;
              } else {
                o[item] = 1;
              }
            }
            var tmpArray = [];
            for (var key in o) {
              if (o[key] == 1) {
                tmpArray.push(key);
              } else {
                if (tmpArray.indexOf(key) == -1) {
                  tmpArray.push(key);
                }
              }
            }
            return tmpArray;
          }
    
          console.log(clearArray(array));
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    1. 写一个函数判断一个字符串中出现次数最多的字符,并统计这个字符出现的次数。比如有这样一个字符串:"daskljahiagnaknscsjdwfanalvnahdpwod"。

    参考源码:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title></title>
      </head>
      <body>
        <script type="text/javascript">
          var str = "daskljahiagnaknscsjdwfanalvnahdpwod";
    
          function max() {
            var o = {};
            for (var i = 0; i < str.length; i++) {
              var item = str.charAt(i);
              if (o[item]) {
                o[item]++;
              } else {
                o[item] = 1;
              }
            }
            var max = 0;
            for (var key in o) {
              if (max < o[key]) {
                max = o[key];
                var tmp;
                tmp = key;
              }
            }
            console.log("出现次数最多的字符是:" + tmp + "出现次数为:" + max);
          }
    
          max(str);
        </script>
      </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35