[TOC]

14.1 严格模式

因为JS是一门很随心 很随意的语言 而且设计之初遗留了很多不好的地方 这就给开发人员制造了很多困扰 而且也有开发人员给开发人员制造的困扰
为了解决这些问题 ES5 中 增加了一个 "严格模式" 严格要求开发人员的代码书写

开启严格模式

在当前作用域的第一行 使用字符串 use strict;

  • 全局严格模式、局部严格模式 ```js

    
    - 声明变量必须使用var
    ```js
    'use strict';  
    // 1 严格模式下 声明变量必须用关键字
    a = 10;
    console.log(a); // a is not defined
    
    • 函数的形参不可以重名

      'use strict'; 
      function demo(a, a, b, c) {
        console.log(a, b, c);
      } 
      demo(1, 2, 3, 4) 
      // Uncaught SyntaxError: Duplicate parameter name not allowed in this context
      
    • 不可以使用八进制

      'use strict';
      // 定义八进制
      var num = 0123;
      console.log(num) 
      // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
      
    • 不可以使用保留字作为变量名

      'use strict';
      var interface = 1;
      console.log(interface)
      //  Uncaught SyntaxError: Unexpected strict mode reserved word
      
    • eval

      // eval是一个函数 它可以把字符串当做代码执行
      var num = eval('1 + 2');
      console.log(num) // 3
      
      'use strict';
      eval("var a = 10; console.log(a)"); // 在严格模式下 eval依然可用 但是会形成一个独立的作用域
      console.log(a)
      
    • 不能删除变量

      'use strict';
      var a = {
      b: 1
      }
      console.log(delete a); 
      // Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
      
    • 不能用arguments.callee ```javascript ‘use strict’; function demo() { console.log(arguments.callee === demo) // true console.log(arguments.callee) // 指向的是当前的函数本身 } demo();

    // Uncaught TypeError: ‘caller’, ‘callee’, and ‘arguments’ properties may not be accessed on strict mode functions or the arguments objects for calls to them

    
    - 不能用with
    ```javascript
    'use strict';
    
    var obj = {
      name: "小明",
      age: 13,
      sex: "女",
      hehe: "呵呵呵呵呵"
    }
    
    var hehe = 'aaaa'
    
    with(obj) {
      console.log(name)
      console.log(age)
      console.log(sex)
      console.log(hehe)
    } 
    // Uncaught SyntaxError: Strict mode code may not include a with statement
    

    14.2 数组方法

    14.2.1 forEach

    arr.forEach(handler)
    handler(value, index, self): 处理函数
    value: 成员
    index: 索引
    self: 原数组

    var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    arr.forEach(function(value, index, self) {
      console.log(value, index, self)
    })
    

    输出
    image.png

    14.2.2 map

    arr.map(handler)
    handler(value, index, self): 处理函数
    value: 成员
    index: 索引
    self: 原数组

    返回值:新数组 取决于handler的返回值

    var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    var arr1 = arr.map(function (value, index, self) {
      return value + "1";
    })
    console.log(arr1)
    

    image.png

    14.2.3 filter

    arr.filter(handler)
    handler(value, index, self): 处理函数
    value: 成员
    index: 索引
    self: 原数组

    返回值:新数组 取决于handler的返回值

    var arr = [
      { type: "大菜", name: "鱼香肉丝", price: 10 },
      { type: "大菜", name: "红烧肉", price: 10 },
      { type: "大菜", name: "香辣粉", price: 10 },
      { type: "中菜", name: "小炒肉", price: 13 },
      { type: "中菜", name: "云吞", price: 14 },
      { type: "小菜", name: "雪糕", price: 15 },
      { type: "小菜", name: "黄瓜", price: 16 }
    ]
    
    var arr1 = arr.filter(function(value) {
      return value.price < 13
    })
    console.log(arr1)
    

    输出:
    image.png

    14.2.4 some

    arr.some(handler)
    handler(value, index, self): 处理函数
    value: 成员
    index: 索引
    self: 原数组

    返回值:布尔值 取决于handler的返回值,如果有任何一个符合条件的,为真,都不符合,为假。

    var arr = [
      { type: "大菜", name: "鱼香肉丝", price: 10 },
      { type: "大菜", name: "红烧肉", price: 10 },
      { type: "大菜", name: "香辣粉", price: 10 },
      { type: "中菜", name: "小炒肉", price: 13 },
      { type: "中菜", name: "云吞", price: 14 },
      { type: "小菜", name: "雪糕", price: 15 },
      { type: "小菜", name: "黄瓜", price: 16 }
    ]
    
    // 判断有没有价格小于13的
    var result = arr.some(function (value) {
      return value.price < 13
    })
    console.log(result)
    

    输出结果image.png

    14.2.5 every

    arr.every(handler)
    handler(value, index, self): 处理函数
    value: 成员
    index: 索引
    self: 原数组

    返回值:布尔值 取决于handler的返回值,如果全部符合条件的,为真,有任一不符合,为假。

    var arr = [
      { type: "大菜", name: "鱼香肉丝", price: 10 },
      { type: "大菜", name: "红烧肉", price: 10 },
      { type: "大菜", name: "香辣粉", price: 10 },
      { type: "中菜", name: "小炒肉", price: 13 },
      { type: "中菜", name: "云吞", price: 14 },
      { type: "小菜", name: "雪糕", price: 15 },
      { type: "小菜", name: "黄瓜", price: 16 }
    ]
    
    // 判断是否全部价格都小于13
    var result = arr.every(function (value) {
      return value.price < 13
    })
    console.log(result)
    

    输出结果:image.png

    14.2.6 fill

    arr.fill(any, start, end) 填充方法
    第一个参数是填充的值
    第二个参数是起始位置(包含)
    第三个参数是结束位置(不包含)

    特点:会改变原数组

    var arr = [1, 2, 3, 4, 5, 6];
    arr.fill("ok"); // ["ok", "ok", "ok", "ok", "ok", "ok"]
    
    var arr1 = [1, 2, 3, 4, 5, 6];
    arr1.fill("ok", 2); // [1, 2, "ok", "ok", "ok", "ok"]
    
    var arr2 = [1, 2, 3, 4, 5, 6];
    arr2.fill("ok", 2, 5); // [1, 2, "ok", "ok", "ok", 6]
    

    输出:image.png

    14.2.7 reduce

    arr.reduce(handler, init) 累计方法
    handler(prev, value, index, self)
    第一个参数是上一个handler返回的值
    第二个参数是成员
    第三个参数是索引
    第四个参数是原数组
    init handler第一次执行时的prev

    返回值:最后一个handler执行的返回值

    var arr = [
      { type: "大菜", name: "鱼香肉丝", price: 10 },
      { type: "大菜", name: "红烧肉", price: 10 },
      { type: "大菜", name: "香辣粉", price: 10 },
      { type: "中菜", name: "小炒肉", price: 13 },
      { type: "中菜", name: "云吞", price: 14 },
      { type: "小菜", name: "雪糕", price: 15 },
      { type: "小菜", name: "黄瓜", price: 16 }
    ]
    var result = arr.reduceRight(function(prev, value) {
      console.log(value)
      return prev + value.price;
    }, 0)
    console.log(result / 7)
    

    均价:image.png

    14.2.8 reduceRight

    同reduce,只是从数组的末尾开始运算。

    14.3 函数方法

    函数也是引用类型,也可以调用方法。

    14.3.1 call

    函数.call(target, …)
    target: 新的this
    后续参数是原函数所需的参数

    function demo(a, b) {
      console.log(this);
      console.log(a, b) 
    }
    demo.call(document.body, 1, 2)  // document.body
    demo.call(document, 1, 3)  // document
    demo.call(document.documentElement, 1, 4) // document.documentElement
    

    14.3.2 apply

    函数.apply(target, arr)
    target: 新的this
    arr: 数组,数组中的每一个值是原函数所需的参数,按照顺序排列

    function demo(a, b) {
      console.log(this);
      console.log(a, b) 
    }
    demo.apply(document.body, [1, 2])  // document.body
    demo.apply(document, [1, 3]) // document
    demo.apply(document.documentElement, [1, 4]) // document.documentElement
    

    总结: call和apply都是ES5之前的方法 作用 都是执行函数并改变函数的this指向 不同:参数的传递方式不同 call是通过平铺的方式传递 而apply是以数组的方式传递

    14.3.3 bind

    ES5中新增的方法

    函数.bind(target)
    target: 新的this

    var demo1 = demo.bind({name:"xiaoming"});
    // bind并不是把原函数中的this给改掉的,而是返回了一个新的函数 让新函数的this是指定的this 但是执行的内容与原函数一致
    demo1() // {name:"xiaoming"}
    demo1() // {name:"xiaoming"}
    demo1() // {name:"xiaoming"}
    demo1() // {name:"xiaoming"}
    demo1() // {name:"xiaoming"}
    demo1() // {name:"xiaoming"}
    

    bind与前两个方法的不同之处在于bind的调用并不会立刻导致函数的执行。而是返回一个新的函数。

    14.4 JSON

    JSON是一种数据格式,它严格要求:

    1. 每一个属性名必须由双引号包裹
      1. 每一个字符串必须由双引号包裹
        1. 不能有注释
        2. 最后一个逗号必须省略

    ES5中,新增了一个JSON对象。

    1. stringify(object | arr) 1. 参数是对象或者数组 2. 返回值 JSON字符串
    2. parse(JSONString) 1. 参数是JSON字符串 2. 返回值 是对象或者数组

      parse方法接受的参数如果不是合格的JSON字符串,则会报错

    如图所示
    image.png