1. 程式人生 > >《JavaScript語言精粹》讀書筆記

《JavaScript語言精粹》讀書筆記

表達 star turn ray 檢索 obj 就是 第四章 遞歸

第三章 對象

  • 檢索
  var obj = {a: 1, b:2, c:3}
obj[a] // obj.a
// 檢索結果是undefined 時用 || 或 && 避免錯誤
obj[a] && obj[b]
  • 反射
var obj = {
  number: 111,
  airline: ‘dsdsds‘
}

// hasOwnProperty檢測對象的屬性
console.log(typeof obj.number) // number
console.log(obj.hasOwnProperty(‘number‘)) // true
console.log(obj.hasOwnProperty(‘number1‘)) // false
  • 枚舉

第四章 函數

調用

js中一共有4中調用模式:

  1. 方法調用模式
  2. 函數調用模式
  3. 構造器調用模式
  4. apply調用模式

  5. 方法調用模式
    //1 方法調用模式
    var myObject = {
        value: 0,
        increment: function(inc) {
            this.value += typeof inc === ‘number‘ ? inc: 1;
        }
    }
    myObject.increment();
document.writeln(myObject.value)/// 1
    myObject.increment(2);
    document.writeln(myObject.value) // 3
    
    // 方法可以使用this訪問自己所屬的對象,所以他能從對象中取值或者對對象進行修改。
    // this到對象的綁定發生在調用的時候。
  1. 函數調用模式
        //2 函數調用模式
        var add = function(a, b) {
            return a+ b;
        }
        var sum = add(3, 4); // 7

            // 給myObject 增加一個double方法
        myObject.double = function() {
            var that = this;
            var helper = function () {
                that.value = add(that.value, that.value);
            }
            helper(); // 以函數的形式調用helper
        }
        // 以方法的形式調用double
        myObject.double();
        console.log(myObject.value) // 6
        // 方法調用函數時,this被綁定到全局對象, 解決方案 : 定義一個變量,將this賦值給它,name內部函數就可以通過that訪問到this
  1. 構造器調用模式 不推薦
        //3 構造器調用模式 不推薦
        var Quo = function(string) {
            this.status = string;
        }
        // 給quo的所有實例提供一個名為get_status的公用方法
        Quo.prototype.get_status = function() {
            return this.status;
        }

        // 構造一個quo的實例
        var myQuo = new Quo(‘confused‘);
    document.writeln(myQuo.get_status()) // confused
    // 如果在一個函數前面帶上new 來調用,那麽背地裏將會創建一個連接到該函數的prototype成員的新對象,同時this會被綁定到那麽新對象上。

  // 使用閉包的方法來調用
    var quo = function(status) {
    return {
      get_status: function() {
        return status
      }
    }
  }
  var myQuo = quo(‘amazed‘)
  console.log(myQuo.get_status()) //amazed
  1. Apply調用模式
        // 4 Apply調用模式
        // Apply方法讓我們構建一個參數數組傳遞給調用的函數,它允許我們選擇this的值。apply方法接收兩個參數,第1個是要綁定給this的值,第2個就是一個參數數組

        var array =[3, 4];
        var sum = add.apply(null, array);
        alert(sum) // 7
        // 構造一個包含status成員的對象
        var statusObject = {
            status: ‘A-OK‘
        }
        // statusobject並沒有繼承自Quo.protoptype,但我們可以在statusobject上調用
        // get_status方法,盡管statusObject並沒有一個名為get_status的方法
        var status = Quo.prototype.get_status.apply(statusObject);
        console.log(status) // A-OK
擴充類型功能
    
    // js允許給語言的基本類型擴充功能; 可以給object。prototype添加方法,可以讓該方法對所有對象都可用。
    // 這樣的方式對函數,數組,字符串,數字,正則表達式和布爾值同樣適用
    Function.prototype.method= function(name, func) {
      this.prototype[name] = func
      return this
    }
    // 通過給function.prototype 增加一個method方法,我們下次給對象曾加方法的時候就不必鍵入prototype這幾個資產,省略掉了一點麻煩
    // 1 給Number.prototype 增加一個integer方法來改善它,他會根據數字的正負來判斷是使用Math.ceiling 還是Math.floor
    Number.method(‘integer‘, function() {
      return  Math[this<0 ? ‘ceil‘: ‘floor‘](this)
    })
    document.writeln((-10/3).integer()) // -3
作用域
var foo = function() {
    var a =3, b=5;
    var bar = function() {
        var b=7, c=11;
        // a =3 b =7 c=11
        a+=b+c // a=21 b=7 c= 11
    }
    // a=3 b=5 c undefined
    bar()
    // a=21 b 5
}
閉包
    // 創建一個名為quo的構造函數
    // 它構造帶有get_status方法和status私有屬性的一個對象
    var quo = function (status) {
      return {
        get_status: function () {
          return status
        }
      }
    }
    // 構造一個quo實例
    var myQuo = quo(‘amazed‘)
    console.log(myQuo.get_status()) //amazed
    // 這個quo函數設計成無需再前面加上new來使用,所以名字也沒有首字母大寫。當我們調用quo時,它返回包含
    // get_status方法並不是訪問該參數的一個副本,它訪問的就是該參數本身。這是可能的;
    // 因為該函數可以訪問它被創建時所處的上下文環境。  這就稱為閉包。
// 定義一個函數,它設置一個DOM節點為黃色,然後把它漸變為白色
var fade = function (node) {
      var level = 1;
      var step = function () {
        var hex = level.toString(16);
        node.style.backgroundColor = ‘#FFFF‘ + hex + hex;
        if (level < 15) {
          level += 1;
          setTimeout(step, 100);
        }
      }
      setTimeout(step, 100);
    }
    fade(document.body) 
記憶
 // 函數可以將先前操作的結果記憶在某個對象裏,從而避免無謂的重復運算。這種優化被稱為記憶
    // 實現一個遞歸函數來計算Fibonacci數列
    // 一個斐波那契數列 數字是之前兩個斐波那契數字之和。 最前面的兩個數字是0 和1 
    var fibonacci = function(n) {
      return n<2 ? n : fibonacci(n-1) +fibonacci(n-2)
    }
    for(var i=0;i<=10; i+=1){
      document.writeln(‘//‘+i+‘:‘ +fibonacci(i))
      //0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
    } 
    // 優化
    // 我們在一個名為memo的數組裏保存我們的存儲結果,存儲結果可以隱藏在閉包中。當函數被調用時,
    // 這個函數首先檢查結果是否已存在,如果已經存在,就立即返回這個結果。
    var fibonacci =function(n) {
      var memo = [0,1]
      var fib=function(n) {
        var result =memo[n]
        if(typeof result !== ‘number‘) {
          result = fib(n-1) +fib(n-2)
          memo[n]=result
        }
        return result
      }
      return fib
    }()
    for(var i=0;i<=10; i+=1){
      document.writeln(‘//‘+i+‘:‘ +fibonacci(i))
      //0:0 //1:1 //2:1 //3:2 //4:3 //5:5 //6:8 //7:13 //8:21 //9:34 //10:55
    }
    // 推廣
    // 我們memoizer函數取得一個初始化memo數組和formula函數。它返回一個管理meno存儲和在需要時調用formula函數的recur函數。
    // 我們把這個recur函數和它的參數傳遞給formula函數
    var memoizer =function (memo, formula){
      var recur = function(n){
        var result = memo[n]
        if(typeof result !== ‘number‘) {
          result = formula(recur, n)
          memo[n] =result
        }
        return result
      }
      return recur
    }
    // 現在,我們可以使用memoizer函數來定義fibonacci函數, 提供其初始的memo數組和formula函數
    var fibonacci = memoizer([0,1], function(recur, n) {
      return recur(n-1) +recur(n-2)
    })

    var factorial = memoizer([1,1], function(recur, n) {
      return n * recur(n-1)
    })

js易混淆的地方

    // 區分數組和對象
    var is_array = function(value) {
      return Object.prototype.toString.apply(value) === ‘[object Array]‘
    }
    console.log(is_array([])) // true

第八章 方法

Array
  • array.concat()
    // concat方法產生一個新數組,它包含一份array的淺復制並把一個或多個參數item附加在後面,如果參數item是一個數組
    // name它的每個元素會被分別添加 類似於 array.push()
    var a = [1,2,3]
    var b= [4,5,6]
    console.log(a.concat(b, true)) //[1, 2, 3, 4, 5, 6, true]
  • array.join()
  • array.pop()
    // pop移除數組中最後一個元素並返回改元素,如果array是空,它返回undefined
    var a = [1,2,3]    
    var c= a.pop()
    console.log(c) // 3
    console.log(a)
  • array.push()
  • array.reverse()
  • array.shift()
  • array.slice()

  • array.sort() 排序
    var n = [4,6,7,1,5]
    n.sort(function(a,b) {
      return a-b
    })
    console.log(n) // [1, 4, 5, 6, 7]

    var m = [‘aa‘,‘bb‘, ‘a‘, 4,8,16,23,42]
    m.sort(function(a, b) {
      if(a ===b) {
        return 0
      }
      if(typeof a === typeof b) {
        return a< b? -1 : 1
      }
      return typeof a <typeof b ? -1 :1
    })
    console.log(m) //[4, 8, 16, 23, 42, "a", "aa", "bb"]
  • array.splice()
  • array.unshift()

    Function
  • function.apply(thisArg, argArray)
    apply方法調用function,傳遞一個會綁定到this上的對象和一個可選的數組作為參數。
    apply方法被用在apply調用模式中
    Function.method(‘bind‘, function(that) {
      // 返回一個函數,調用這個函數就像調用那個對象 的一個方法
      var method = this,
      slice = Array.prototype.slice,
      args = slice.apply(arguments, [1])
      return function() {
        return method.apply(that, args.concat(slice.apply(arguments, [0])))
      }
    })
    var x = function() {
      return this.value
    }.bind({value: 666})
    alert(x())
  • object.hasOwnProperty(name)
    如果這個object包含一個名為name的屬性,n那麽hasOwnProperty方法返回true

    RegExg
    regexp.exec(string)
    如果匹配成功regexp和字符串string,它會返回一個數組。
    數組中的下標未0的元素將包含正則表達式regexp匹配的子字符串
  • regexp.test(string)
    返回 true 和false

String
  • string.charAt()
  • string.charCodeAt()
  • string.concat()
  • string.indexOf()
    返回 -1 未找到 找到返回位置
  • string.lastIndexOf()
  • string.match(regexp)
    字符串和正則匹配 和全局匹配 g
  • string.replace(searchValue, replaceValue)
    對string進行查找和替換操作,並返回一個新的字符串。
var reg = /\((\d{3})\)/g
var p = ‘(555)666-1212‘.replace(reg, ‘$1-‘)
console.log(p) //555-666-1212
  • string.search(regexp)
    search方法和indexOf方法類似,接收一個正則表達式對象作為參數而不是一個字符串
    找到匹配 返回第一匹配的位置,沒有返回-1
var text = ‘and in it he says "Any damn fool could‘
var pos = text.search(/["‘]/) // 18
  • string.slice(start, end)
    如果start/end是負數,他將與string.length相加。end參數是可選參數,默認string.length
  • string.split(separator, limit)
    把string分割成片段來創建一個字符串數組。
  • string.substring(start, end)
    和slice()的用法一樣, 不能處理負數參數
  • string.toLocaleLowerCase()
  • string.toLocaleUpperCase()

《JavaScript語言精粹》讀書筆記