1. 程式人生 > >【ECMAScript 5_6_7】1、ES5特性總結

【ECMAScript 5_6_7】1、ES5特性總結

一、嚴格模式

1. 理解:
  * 除了正常執行模式(混雜模式),ES5添加了第二種執行模式:"嚴格模式"(strict mode)。
  * 顧名思義,這種模式使得Javascript在更嚴格的語法條件下執行
2.  目的/作用
 * 消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為
 * 消除程式碼執行的一些不安全之處,為程式碼的安全執行保駕護航
 * 為未來新版本的Javascript做好鋪墊
3. 使用
  * 在全域性或函式的第一條語句定義為: 'use strict';
  * 如果瀏覽器不支援, 只解析為一條簡單的語句, 沒有任何副作用
4. 語法和行為改變
 * 必須用var宣告變數
 * 禁止自定義的函式中的this指向window
 * 建立eval作用域
 * 物件不能有重名的屬性

 <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_嚴格模式</title>
</head>
<body>
<script type="text/javascript">
  'use strict'
  //1.必須用var宣告變數
  var a = '123'  // a = '123 非嚴格模式下相當於 window.a = '123'
  console.log(a)

  //2.禁止自定義的函式中的this指向window
  function Person(name,age) {
    this.name =  name
    this.age = age
    console.log(this)  // new建構函式時this指向Person,直接呼叫this指向window
  }
  new Person()  // 此時若沒有new構造該函式,相當於直接呼叫該函式方法,this指向window在嚴格模式下是禁止的
  setTimeout(function () {
    console.log(this)  // window
  },1000)

  //3.嚴格模式下會建立eval作用域
  var price = 100
  eval('var price = 200;alert(price)')  // 非嚴格模式下eval內沒有作用域,定義的變數相當於全域性變數,會汙染全域性,有安全隱患
  alert(price)

  //物件不能有重名的屬性
  var onedean = {
    height:177
    weight:120
    // height: 177 // 嚴格模式下禁止
  }

</script>

</body>
</html>

二、JSON物件

1. JSON.stringify(obj/arr)
  * js物件(陣列)轉換為json物件(陣列)
2. JSON.parse(json)
  * json物件(陣列)轉換為js物件(陣列)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02_JSON物件</title>
</head>
<body>
<script type="text/javascript">
  var obj1 ={
    name:'onedean',
    age:20
  }
  var obj2 = [
    'one',123,true
  ]
  //1.JSON.stringify()將js物件或陣列轉換為json物件或陣列(字串)
  obj1 = JSON.stringify(obj1)
  obj2 = JSON.stringify(obj2)
  console.log(typeof obj1,typeof obj2)  // string string
  //2.JSON.parse()將json物件或陣列(字串)轉換為js物件或陣列
  obj1 = JSON.parse(obj1)
  obj2 = JSON.parse(obj2)
  console.log(typeof obj1,typeof obj2)  // object object
</script>
</body>
</html>

 三、Object擴充套件(1)

ES5給Object擴充套件了一些靜態方法, 常用的2個:
1. Object.create(prototype, [descriptors])
  * 作用: 以指定物件為原型建立新的物件
  * 為新的物件指定新的屬性, 並對屬性進行描述
    - value : 指定值
    - writable : 標識當前屬性值是否是可修改的, 預設為false
    - configurable: 標識當前屬性是否可以被刪除 預設為false
    - enumerable: 標識當前屬性是否能用for in 列舉 預設為false
2. Object.defineProperties(object, descriptors)
  * 作用: 為指定物件定義擴充套件多個屬性
    * get :用來獲取當前屬性值得回撥函式
    * set :修改當前屬性值得觸發的回撥函式,並且實參即為修改後的值
   * 存取器屬性:setter,getter一個用來存值,一個用來取值

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03_Object擴充套件</title>
</head>
<body>
<script type="text/javascript">
  // 1. Object.create(prototype, [descriptors])
  var obj = {name:'onedean',age:20}
  var obj1 ={}
  console.log(obj)
  console.log(obj1)
  obj1 = Object.create(obj,{  // 此時obj1的隱式原型指向obj,屬性值新增一個sex:'男'
    sex:{
      value:'男',
      writable:true,  // 預設當前屬性值不可修改,此處修改為可改
      configurable:true,  // 預設當前屬性值不可刪除,此處修改為可刪除
      enumerable:true  // 預設當前屬性值不能for in列舉(列舉的是之前隱式原型指向的obj的屬性),此處修改為可列舉
    }
  })
  console.log(obj1)
  obj1.sex = '女'
  console.log(obj1.sex)
  for(var i in obj1){
    console.log(i)
  }
  delete obj1.sex
  console.log(obj1)

  // 2. Object.defineProperties(object, descriptors)
  var obj2 = {
    firstName:'one',
    lastName:'dean'
  }
  Object.defineProperties(obj2,{
    fullName:{
      get:function () {  // 獲取擴充套件屬性的值,獲取擴充套件屬性值時get方法才會自動呼叫(惰性求值)
        return this.firstName + '-' + this.lastName
      },
      set:function (data) { // 監聽擴充套件屬性,當擴充套件屬性發生變化的時候會自動呼叫,自動呼叫後會將變化的值作為實參注入到set函式的形參
        var names = data.split('-')
        this.firstName = names[0]
        this.lastName = names[1]
      }
    }
  })
  console.log(obj2.fullName)
  obj2.fullName = 'di-yuan'
  console.log(obj2.fullName)

</script>
</body>
</html>

四、Object擴充套件(2)

物件本身的兩個方法
* get propertyName(){} 用來得到當前屬性值的回撥函式
* set propertyName(){} 用來監視當前屬性值變化的回撥函式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type='text/javascript'>
    var obj = {
        firstName:'one',
        lastName:'dean',
        get fullName(){
            return this.firstName + '-' + this.lastName
        },
        set fullName(data){
            var names = data.split('-')
            this.firstName = names[0]
            this.lastName = names[1]
        }
    }
    console.log(obj)  // 注意觀察和下面object的屬性值
    console.log(obj.fullName)
    obj.fullName = 'di-yuan'
    console.log(obj.fullName)
    console.log(obj)  // 注意觀察和上面object的屬性值
</script>
</body>
</html>

 五、Array擴充套件

1. Array.prototype.indexOf(value) : 得到值在陣列中的第一個下標
2. Array.prototype.lastIndexOf(value) : 得到值在陣列中的最後一個下標
3. Array.prototype.forEach(function(item, index){}) : 遍歷陣列
4. Array.prototype.map(function(item, index){}) : 遍歷陣列返回一個新的陣列,返回加工之後的值
5. Array.prototype.filter(function(item, index){}) : 遍歷過濾出一個新的子陣列, 返回條件為true的值

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04_Array擴充套件</title>
</head>
<body>
<script type="text/javascript">
  /*
   需求:
   1. 輸出第一個4的下標
   2. 輸出最後一個4的下標
   3. 輸出所有元素的值和下標
   4. 根據arr產生一個新陣列,要求每個元素都比原來大10
   5. 根據arr產生一個新陣列, 返回的每個元素要大於4
   */
  var arr = [5,8,4,2,3,4,7,1,0]
  // 1. Array.prototype.indexOf(value) : 得到值在陣列中的第一個下標
  console.log(arr.indexOf(4))

  // 2. Array.prototype.lastIndexOf(value) : 得到值在陣列中的最後一個下標
  console.log(arr.lastIndexOf(4))
  // 3. Array.prototype.forEach(function(item, index){}) : 遍歷陣列
  arr.forEach(function (item,index) {
    console.log(index,item)
  })
  // 4. Array.prototype.map(function(item, index){}) : 遍歷陣列返回一個新的陣列,返回加工之後的值
  var arr2 = arr.map(function (item) {
    return item+10
  })
  console.log(arr2)
  // 5. Array.prototype.filter(function(item, index){}) : 遍歷過濾出一個新的子陣列, 返回條件為true的值
  var arr3 = arr.filter(function (item) {
    return item>4
  })
  console.log(arr3)
</script>
</body>
</html>

六、Function擴充套件

1. Function.prototype.bind(obj) :
  * 作用: 將函式內的this繫結為obj, 並將函式返回
2. 面試題: 區別bind()與call()和apply()?
  * 都能指定函式中的this
  * call()/apply()是立即呼叫函式
  * bind()是將函式返回

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>05_Function擴充套件</title>
</head>
<body>
<script type="text/javascript">
  var obj = {username:'ondean'}
  function person(data) {
    console.log(this)
    console.log(data)
  }
  person()
  // call()和apply()的區別:傳入引數的形式
  person.call(obj,10)  // 直接從第二個引數開始,一次傳入
  person.apply(obj,[10])  // 第二個引數必須是陣列,傳入存放在陣列

  /*var obj2 = person.bind(obj)
  console.log(obj2)
  obj2(10)*/
  person.bind(obj)(10)

  setTimeout(function () {  // 多使用bind將函式內的this繫結為obj,因為不會立即呼叫
    console.log(this)
  }.bind(obj),1000)

</script>
</body>
</html>