鍍金池/ 教程/ Android/ <a rel="nofollow" href="http://www.infoq.com/cn/es6-in-depth/"">
Launch mode 和 Intent flags專題
Canvas &amp; Drawables
UTAustinX_UT.9.01x: Effective Thinking Through Mathematics
《JavaScript 語言精粹》
Memory leak專題
React基礎(chǔ)
《Test Driven Development: By Example》一書
Developer tools
安卓開發(fā)技能樹
<a rel="nofollow" href="https://mp.weixin.qq.com/s?__biz=MzA3NDM
Best Practices for Interaction and Engagement
各個(gè)安卓版本引入的主要新特性
Building Apps with Connectivity &amp; the Cloud
List.toArray()再強(qiáng)轉(zhuǎn)是一定會(huì)失敗的
深入Android frameworks
Google dev 100 days系列視頻
Building Apps with Contacts &amp; Sign-In
關(guān)系型數(shù)據(jù)庫設(shè)計(jì)范式
《App研發(fā)錄》一書
REST API設(shè)計(jì)
Google IO 2015摘要
自定義View/ViewGroup以及高性能實(shí)現(xiàn)自定義UI
安卓系統(tǒng)點(diǎn)擊事件處理
《50 Android Hacks》一書
Building Apps with Content Sharing
Flux基礎(chǔ)
<a rel="nofollow" href="http://developer.android.com/training/in
依賴注入(以Dagger 2為例)
Java同步機(jī)制
Java對(duì)象內(nèi)存的使用情況
JSR133(Java memory model)
Google官方Material Design手冊(cè)(<a rel="nofollow" href="http://develop
Futurice公司安卓團(tuán)隊(duì)的建議
安卓性能優(yōu)化
  • 1.
Best Practices for Performance
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
<a rel="nofollow" href="http://blog.danlew.net/2014/11/19/styles
Handling Runtime Changes
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
Building Apps with Graphics &amp; Animation
<a rel="nofollow" href="http://tools.android.com/tech-docs/new-b
Android項(xiàng)目架構(gòu)
MVP(Model-View-Presenter)模式
<a rel="nofollow" href="http://www.infoq.com/cn/es6-in-depth/"">
《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》一書
Rx在Android中的最佳實(shí)踐
函數(shù)調(diào)用時(shí),傳遞參數(shù)應(yīng)該是不可變的(Immutable)
ProGuard
面向?qū)ο罅笤瓌t(SOLID+)
深入理解Java虛擬機(jī)
深入Java深淺拷貝、immutable、unmodifiable
Best Practices for User Input
UI上的一些高效方式/最佳實(shí)踐
<a rel="nofollow" href="https://blog.stylingandroid.com/ripples-
Best Practices for User Interface
安卓測試驅(qū)動(dòng)開發(fā)/安卓測試驗(yàn)證
暗時(shí)間:學(xué)會(huì)正確思考
技術(shù)筆記
Aspect Oriented Programming(AOP)
Best Practices for Background Jobs
安卓系統(tǒng)動(dòng)效專題
Feed系統(tǒng)的設(shè)計(jì)
Data binding(MVVM,Model-View-ViewModel)
Effective Java一書筆記
<a rel="nofollow" href="http://developer.android.com/training/in
Rx (Reactive eXtention)
MultiDex專題
一些很棒的點(diǎn)子
WebRTC

<a rel="nofollow" href="http://www.infoq.com/cn/es6-in-depth/"">

迭代器和for-of循環(huán)

  • 不要用for-in循環(huán)遍歷數(shù)組,它是用于遍歷普通對(duì)象的各個(gè)屬性的key的;
  • for-of循環(huán)可以用來遍歷數(shù)組,沒有for-in的缺陷,也沒有forEach的缺陷:無法break, continue, return;
  • for-in循環(huán)用來遍歷對(duì)象屬性,for-of循環(huán)用來遍歷數(shù)據(jù):例如數(shù)組中的值;
  • for-of還支持其他集合的遍歷(Map, Set),也能用于字符串遍歷(視其為Unicode字符數(shù)組);

    for (var value of myArray) {
      console.log(value);
    }
    
    var uniqueWords = new Set(words);
    for (var word of uniqueWords) {
      console.log(word);
    }
    
    for (var [key, value] of phoneBookMap) {
      console.log(key + "'s phone number is: " + value);
    }
  • for-of循環(huán)語句通過方法調(diào)用(迭代器方法)來遍歷各種集合
  • 迭代器對(duì)象

    • 擁有[Symbol.iterator]()的對(duì)象被稱為可迭代的
    • 迭代器對(duì)象可以是任意具有.next()方法的對(duì)象
    • for-of循環(huán)將重復(fù)調(diào)用這個(gè)方法,每次循環(huán)調(diào)用一次
    var zeroesForeverIterator = {
    [Symbol.iterator]: function () {
      return this;
      },
      next: function () {
      return {done: false, value: 0};
    }
    };

生成器 Generators

function* quips(name) {
  yield "你好 " + name + "!";
  yield "希望你能喜歡這篇介紹ES6的譯文";
  if (name.startsWith("X")) {
    yield "你的名字 " + name + "  首字母是X,這很酷!";
  }
  yield "我們下次再見!";
}
  • 普通函數(shù)使用function聲明,而生成器函數(shù)使用function*聲明。
  • 在生成器函數(shù)內(nèi)部,有一種類似return的語法:關(guān)鍵字yield。二者的區(qū)別是,普通函數(shù)只可以return一次,而生成器函數(shù)可以yield多次(當(dāng)然也可以只yield一次)。在生成器的執(zhí)行過程中,遇到yield表達(dá)式立即暫停,后續(xù)可恢復(fù)執(zhí)行狀態(tài)。
  • 這就是普通函數(shù)和生成器函數(shù)之間最大的區(qū)別,普通函數(shù)不能自暫停,生成器函數(shù)可以。
  • 執(zhí)行效果:
> var iter = quips("jorendorff");
  [object Generator]
> iter.next()
  { value: "你好 jorendorff!", done: false }
> iter.next()
  { value: "希望你能喜歡這篇介紹ES6的譯文", done: false }
> iter.next()
  { value: "我們下次再見!", done: false }
> iter.next()
  { value: undefined, done: true }
  • 調(diào)用一個(gè)生成器時(shí),它并非立即執(zhí)行,而是返回一個(gè)已暫停的生成器對(duì)象,以后對(duì)其每調(diào)用一次.next()方法,函數(shù)調(diào)用將其自身解凍并一直運(yùn)行到下一個(gè)yield表達(dá)式,再次暫停。
  • 調(diào)用最后一個(gè)iter.next()時(shí),我們最終抵達(dá)生成器函數(shù)的末尾,所以返回結(jié)果中done的值為true
  • 每當(dāng)生成器執(zhí)行yield語句,生成器的堆棧結(jié)構(gòu)(本地變量、參數(shù)、臨時(shí)值、生成器內(nèi)部當(dāng)前的執(zhí)行位置)被移出堆棧。然而,生成器對(duì)象保留了對(duì)這個(gè)堆棧結(jié)構(gòu)的引用(備份),所以稍后調(diào)用.next()可以重新激活堆棧結(jié)構(gòu)并且繼續(xù)執(zhí)行。
  • 值得特別一提的是,生成器不是線程,當(dāng)生成器運(yùn)行時(shí),它和調(diào)用者處于同一線程中,擁有確定的連續(xù)執(zhí)行順序,永不并發(fā)。
  • 與系統(tǒng)線程不同的是,生成器只有在其函數(shù)體內(nèi)標(biāo)記為yield的點(diǎn)才會(huì)暫停。
  • 生成器的作用
    • 生成器是迭代器:所有的生成器都有內(nèi)建.next()[Symbol.iterator]()方法的實(shí)現(xiàn)。你只須編寫循環(huán)部分的行為。
    • 使任意對(duì)象可迭代。編寫生成器函數(shù)遍歷這個(gè)對(duì)象,運(yùn)行時(shí)yield每一個(gè)值。然后將這個(gè)生成器函數(shù)作為這個(gè)對(duì)象的[Symbol.iterator]方法。
    • 簡化數(shù)組構(gòu)建函數(shù)。
      • 獲取異常尺寸的結(jié)果。例如無限長的數(shù)組。
      • 重構(gòu)復(fù)雜循環(huán)。
      • 構(gòu)建與迭代相關(guān)的工具。
    • lazy計(jì)算。僅當(dāng)需要時(shí)進(jìn)行計(jì)算。
  • .next可選參數(shù)
  • .return
  • .throw
  • yield*

模板字符串

function authorize(user, action) {
  if (!user.hasPrivilege(action)) {
    throw new Error(
      `用戶 ${user.name} 未被授權(quán)執(zhí)行 ${action} 操作。`);
  }
}
  • 反撇號(hào)(`)基礎(chǔ)知識(shí)
    • 模板占位符中的代碼可以是任意JavaScript表達(dá)式,所以函數(shù)調(diào)用、算數(shù)運(yùn)算等這些都可以作為占位符使用,你甚至可以在一個(gè)模板字符串中嵌套另一個(gè),我稱之為模板套構(gòu)(template inception)。
    • 如果這兩個(gè)值都不是字符串,可以按照常規(guī)將其轉(zhuǎn)換為字符串。例如:如果action是一個(gè)對(duì)象,將會(huì)調(diào)用它的.toString()方法將其轉(zhuǎn)換為字符串值。
    • 如果你需要在模板字符串中書寫反撇號(hào)、${,你必須使用反斜杠將其轉(zhuǎn)義。
    • 模板字符串可以多行書寫,模板字符串中所有的空格、新行、縮進(jìn),都會(huì)原樣輸出在生成的字符串中。
  • 反撇號(hào)的未來
    • 它們不會(huì)為你自動(dòng)轉(zhuǎn)義特殊字符
    • 它們無法很好地與國際化庫相配合
    • 它們不能替代模板引擎的地位

不定參數(shù)和默認(rèn)參數(shù)

  • 以前的版本中有“神奇的arguments對(duì)象”,ES6引入了與其他語言類似的不定參數(shù)語法:
function containsAll(haystack, ...needles) {
  for (var needle of needles) {
    if (haystack.indexOf(needle) === -1) {
      return false;
    }
  }
  return true;
}
  • 如果沒有額外的參數(shù),不定參數(shù)就是一個(gè)空數(shù)組,它永遠(yuǎn)不會(huì)是undefined。
  • 默認(rèn)參數(shù)也與c++類似,但有幾點(diǎn)需要注意
    • 默認(rèn)值表達(dá)式在函數(shù)調(diào)用時(shí)自左向右求值,這一點(diǎn)與Python不同。這也意味著,默認(rèn)表達(dá)式可以使用該參數(shù)之前已經(jīng)填充好的其它參數(shù)值。
    • 傳遞undefined值等效于不傳值,將使用定義的默認(rèn)值
    • 沒有默認(rèn)值的參數(shù)隱式默認(rèn)為undefined
  • 停止使用arguments

解構(gòu)(Destructuring)

  • 數(shù)組與迭代器的解構(gòu)

    [ variable1, variable2, ..., variableN ] = array;
    • 可以對(duì)任意深度的嵌套數(shù)組進(jìn)行解構(gòu)
    • 可以在對(duì)應(yīng)位留空來跳過被解構(gòu)數(shù)組中的某些元素

      var [,,third] = ["foo", "bar", "baz"];
    • 還可以通過“不定參數(shù)”模式捕獲數(shù)組中的所有尾隨元素
    • 當(dāng)訪問空數(shù)組或越界訪問數(shù)組時(shí),對(duì)其解構(gòu)與對(duì)其索引的行為一致,最終得到的結(jié)果都是:undefined
    • 數(shù)組解構(gòu)賦值的模式同樣適用于任意迭代器

      function* fibs() {
        var a = 0;
        var b = 1;
        while (true) {
          yield a;
          [a, b] = [b, a + b];
        }
      }
      var [first, second, third, fourth, fifth, sixth] = fibs();
      console.log(sixth);
      // 5
  • 對(duì)象的解構(gòu)

    var robotA = { name: "Bender" };
    var { name: nameA } = robotA;
    console.log(nameA);
    // "Bender"
    
    var { foo, bar } = { foo: "lorem", bar: "ipsum" };
    console.log(foo);
    // "lorem"
    
    var { missing } = {};
    console.log(missing);
    // undefined
    • 首先指定被綁定的屬性,然后緊跟一個(gè)要解構(gòu)的變量。
    • 當(dāng)屬性名與變量名一致時(shí),可以通過一種實(shí)用的句法簡寫。
    • 可以隨意嵌套并進(jìn)一步組合對(duì)象解構(gòu)
    • 解構(gòu)一個(gè)未定義的屬性時(shí),得到的值為undefined
  • 解構(gòu)值不是對(duì)象、數(shù)組或迭代器

    var {blowUp} = null;
    // TypeError: null has no properties(null沒有屬性)
    
    var {wtf} = NaN;
    console.log(wtf);
    // undefined
    • 當(dāng)你嘗試解構(gòu)null或undefined時(shí),你會(huì)得到一個(gè)類型錯(cuò)誤
    • 可以解構(gòu)其它原始類型,例如:布爾值、數(shù)值、字符串,但是你將得到undefined
  • 當(dāng)你要解構(gòu)的屬性未定義時(shí)你可以提供一個(gè)默認(rèn)值:

    var [missing = true] = [];
    console.log(missing);
    // true
  • 解構(gòu)的實(shí)際應(yīng)用
    • 函數(shù)參數(shù)定義:函數(shù)接收一個(gè)對(duì)象,將不同的實(shí)際參數(shù)作為對(duì)象屬性,以避免讓API使用者記住多個(gè)參數(shù)的使用順序。
    • 配置對(duì)象參數(shù):通過默認(rèn)值實(shí)現(xiàn)
    • 與ES6迭代器協(xié)議協(xié)同使用:for (var [key, value] of map) { //... }
    • 多重返回值

箭頭函數(shù)(Arrow Functions)

符號(hào) 含義
<!-- 單行注釋
--> “趨向于”操作符
<= 小于等于
=> 這又是什么?
  • 箭頭函數(shù):=>,用于lambda語法
  • 使用了塊語句的箭頭函數(shù)不會(huì)自動(dòng)返回值,你需要使用return語句將所需值返回。
  • 當(dāng)使用箭頭函數(shù)創(chuàng)建普通對(duì)象時(shí),你總是需要將對(duì)象包裹在小括號(hào)里。
    • puppy => {}會(huì)被解析為沒有任何行為并返回undefined的箭頭函數(shù)。
  • 箭頭函數(shù)沒有它自己的this

    • 通過object.method()語法調(diào)用的方法使用非箭頭函數(shù)定義,這些函數(shù)需要從調(diào)用者的作用域中獲取一個(gè)有意義的this值。
    • 其它情況全都使用箭頭函數(shù)。
    • 箭頭函數(shù)不會(huì)獲取它們自己的arguments對(duì)象
    • ES6的方法語法

      // ES6
      {
        ...
        addAll: function addAll(pieces) {
          _.each(pieces, piece => this.add(piece));
        },
        ...
      }
      
      // ===>>>
      
      // ES6的方法語法
      {
        ...
        addAll(pieces) {
          _.each(pieces, piece => this.add(piece));
        },
        ...
      }

Symbols

// 創(chuàng)建一個(gè)獨(dú)一無二的symbol
var isMoving = Symbol("isMoving");
...
if (!element[isMoving]) {
  smoothAnimations(element);
}
element[isMoving] = true;
  • Symbol是JavaScript的第七種原始類型:Undefined 未定義,Null 空值,Boolean 布爾類型,Number 數(shù)字類型,String 字符串類型,Object 對(duì)象類型
  • 以symbol為鍵的屬性屬性與數(shù)組元素類似,不能被類似obj.name的點(diǎn)號(hào)法訪問,你必須使用方括號(hào)訪問這些屬性。
  • 只有當(dāng)isMoving在當(dāng)前作用域中時(shí)才會(huì)生效
  • JavaScript中最常見的對(duì)象檢查的特性會(huì)忽略symbol鍵,例如:for-in循環(huán),Object.keys(obj)Object.getOwnPropertyNames(obj)
  • Object.getOwnPropertySymbols(obj)可以列出對(duì)象的symbol鍵;
  • Reflect.ownKeys(obj),會(huì)同時(shí)返回字符串鍵和symbol鍵
  • symbol被創(chuàng)建后就不可變更,你不能為它設(shè)置屬性(在嚴(yán)格模式下嘗試設(shè)置屬性會(huì)得到TypeError的錯(cuò)誤)。他們可以用作屬性名稱,這些性質(zhì)與字符串類似。
  • 每一個(gè)symbol都獨(dú)一無二,不與其它symbol等同,即使二者有相同的描述也不相等
  • symbol不能被自動(dòng)轉(zhuǎn)換為字符串,這和語言中的其它類型不同。嘗試拼接symbol與字符串將得到TypeError錯(cuò)誤。通過String(sym)或sym.toString()可以顯示地將symbol轉(zhuǎn)換為一個(gè)字符串。
  • 獲取symbol的三種方法
    • 調(diào)用Symbol()
    • 調(diào)用Symbol.for(string),如果同一個(gè)描述的symbol已經(jīng)存在,將返回已存在的symbol對(duì)象
    • 使用標(biāo)準(zhǔn)定義的symbol,例如:Symbol.iterator。標(biāo)準(zhǔn)根據(jù)一些特殊用途定義了少許的幾個(gè)symbol。

集合

  • 已經(jīng)有了一種類似哈希表的東西:對(duì)象(Object)。
  • 作為查詢表使用的對(duì)象,不能既支持方法又保證避免沖突。
  • 因而,要么得用Object.create(null)而非直接寫{},要么得小心地避免把Object.prototype.toString之類的內(nèi)置方法名作為鍵名來存儲(chǔ)數(shù)據(jù)。
  • 對(duì)象的鍵名總是字符串(當(dāng)然,ES6 中也可以是Symbol)而不能是另一個(gè)對(duì)象。
  • 沒有有效的獲知屬性個(gè)數(shù)的方法。
  • 純粹的對(duì)象不可遍歷,也就是,它們不能配合for-of循環(huán)或...操作符等語法。
  • 集合數(shù)據(jù)的訪問,不能再通過屬性方式了,只能通過暴露出來的接口(get等)。
  • Set, Map, WeakMap, WeakSet

代理(Proxy)

  • 對(duì)象的14種內(nèi)部方法。
  • var proxy = new Proxy(target, handler);
  • 代理的行為很簡單:將代理的所有內(nèi)部方法轉(zhuǎn)發(fā)至目標(biāo)。簡單來說,如果調(diào)用proxy.[[Enumerate]](),就會(huì)返回target.[[Enumerate]]()。
  • 句柄對(duì)象的方法可以覆寫任意代理的內(nèi)部方法。

類(Class),繼承

...

  • 實(shí)例屬性,方法?
  • 靜態(tài)屬性,方法?
  • prototype?

letconst

  • ES6之前,只有兩種作用域:全局,函數(shù),沒有代碼塊作用域
  • var是函數(shù)作用域
  • 變量提升(hoisting)
  • ES6引入了新的作用域:代碼塊作用域;letconst都是這一作用域;

模塊

上一篇:REST API設(shè)計(jì)下一篇:WebRTC