ECMAScript 5 新特性 vol.4 - JSON / 雜項

JSON

咱們已經很熟悉JSON.parseJSON.stringify了,然而他們還有一些不爲人知的用法。數組

JSON.parse

將JSON字符串解析爲Object,常規調用方式:app

var string = '{"name":"kid", "age":18}'
  var result = JSON.parse(string)
  // -> { name: 'kid', age: 18 }

除此以外還能額外傳一個回調函數,它會遍歷每個key-value:函數

var string = '{"name":"kid", "age":18}'
  JSON.parse(string, function(key, value){
    console.log(key, value)
    return value
  })
  // -> 'name' 'kid'
  // -> 'age' 18
  // -> '' {name: "kid", age: 18}

注意,最後會有一次額外的迭代,key始終爲空字符串,而value則是整個對象,我將其理解爲最外層的屬性(不太恰當?)this

當對象中嵌套對象時,則從裏至外遍歷,同級的從左到右:prototype

var string = '{"A": {"B": {"C": true, "D": false}}}'
  JSON.parse(string, function(key, value){
    console.log(key, value)
    return value
  })
  // -> 'C': true
  // -> 'D': false
  // -> 'B': {C: true, D: false}
  // -> 'A': {B: Object}
  // -> '': {A: Object}

回調函數的this將指向當前迭代屬性的父屬性:code

var string = '{"A": {"B": {"C": true, "D": false}}}'
  var result = JSON.parse(string, function(key, value){
    console.log(this)
    return value
  })
  // -> Object {C: true, D: false}
  // -> Object {C: true, D: false}
  // -> Object {B: Object}
  // -> Object {A: Object}
  // -> Object {"": Object}

每一次迭代,你均可以經過return改變屬性的值。若返回undefined,那麼這個屬性將被剔除:對象

var string = '{"name":"kid", "age":18}'
  var result = JSON.parse(string, function(key, value){
    switch( key ){
      case 'name': return undefined
      case 'age': return value + 5
      case '': console.log(value); return value
    }
  })
  console.log(result)
  // -> { age: 23 }

這是種過濾與映射的語法糖,但若是某次迭代你忘記返回值,或最外層返回的不是原值,那麼整個JSON數據就再也不正確。鑑於這點,我認爲不該該依賴這種方式,尤爲是在團隊合做時,儘可能避免生疏的用法纔是正道。ip

JSON.stringify

將Object解析爲JSON字符串,常規調用方式:字符串

var man = {
    name: 'kid',
    age: 18
  }
  var string = JSON.stringify( man )  // -> '{"name":"kid","age":18}'

能夠設置白名單數組來過濾屬性:get

var man = {
    name: 'kid',
    age: 18
  }
  var string = JSON.stringify( man, ['name'] )  // -> '{"name":"kid"}'

JSON.parse相似,能夠傳入回調函數來迭代屬性,

var man = {
    name: 'kid',
    age: 18
  }
  var string = JSON.stringify(man, function( key, value ){
    switch( key ){
      case 'name': return undefined
      case 'age': return value + 5
      case '': return value
    }
  })
  console.log(string)  // -> '{"age":23}'

還有很是實用的格式化功能,第三個參數若爲數字,則表明每一層級的屬性縮進幾個空格(第二個參數爲null,是由於這裏不演示迭代函數,請知曉):

var man = {
    name: 'kid',
    pet: {
      name: 'mimi',
      type: 'cat'
    }
  }
  var string = JSON.stringify(man, null, 4)
  console.log(string)
  // ->
  // '{
  //   "name": "kid",
  //   "pet": {
  //       "name": "mimi",
  //       "type": "cat"
  //   }
  // }'

也能夠指定任意字符串做爲縮進:

var man = {
    name: 'kid',
    pet: {
      name: 'mimi',
      type: 'cat'
    }
  }
  var string = JSON.stringify(man, null, '**')
  console.log(string)
  // ->
  // '{
  // **"name": "kid",
  // **"pet": {
  // ****"name": "mimi",
  // ****"type": "cat"
  // **}
  // }'

Function.prototype.bind

以往要爲函數指定this,須要使用callapply,而在ES5中則有更直截了當的方式:

function fn(){
    console.log(this)
  }
  fn = fn.bind({ name: 'kid' })
  fn()  // { name: 'kid' }

我想下例狀況不少人都碰見過,這時通常會用selfthat之類的臨時變量代替this

function Team(){
    this.members = ['John','Mary','Andy']
    this.food = 'chicken'
  }
  
  Team.prototype.eat = function(){
    var self = this
    this.members.forEach(function(member){
      console.log(member+' eat '+self.food)
    })
  }
  
  var team = new Team()
  team.eat()

而有了bind,則能夠在內層函數也冠冕堂皇使用this,代碼優雅了一些:

function Team(){
    this.members = ['John','Mary','Andy']
    this.food = 'chicken'
  }
  
  Team.prototype.eat = function(){
    this.members.forEach(function(member){
      console.log(member+' eat '+this.food)
    }.bind(this))
  }
  
  var team = new Team()
  team.eat()

Date.prototype.toISOString

ISO 8601的格式來初始化或輸出時間,不做過多說明:

var date = new Date("2015-12-25T21:07:35.000Z")
  date.toISOString()  // 2015-12-25T21:07:35.000Z

String.prototype.trim

終於有一個內置方法,可讓咱們去除字符串頭尾的空白符了:

var string = '  hello, world ~ !  '
  string = string.trim()  // -> 'hello, world ~ !'

原創,自由轉載,請署名,本人博客 kid-wumeng.me

相關文章
相關標籤/搜索