let test = 'test string'; let str = 'this is a '+ test; let str2 = `this is a ${test}`;//推薦用法,注意這裏的`號不是單引號
由於模板字符串爲es6的語法,不建議在前端js使用,由於目前瀏覽器對es6支持不完整前端
** !!**mysql
let obj = null; let boolean = !!(''); //使用兩個邏輯非能夠獲取準確的布爾值結果
** ||**es6
if(obj === null || obj === '' || obj === undefined || obj === 0){ obj = ''; }
簡化爲:sql
obj = obj || '';//此處注意obj的值在什麼狀況下是false
** &&**數據庫
if(obj !== null){ obj = 'has value'; }
簡化爲:數組
obj !== null && (obj = 'has value');
** ~**promise
if(str.indexOf('a') > -1){ ... }
簡化爲:瀏覽器
if(~str.indexOf('a')){ ... }
多條件分支語句若是執行邏輯相似或相同時,可使用簡化寫法。(邏輯不一樣也能夠,但須要提取爲獨立的處理方法)babel
if寫法markdown
if(flag == 1){ retrun test1(); }else if(flag == 2){ return test2(); }else if(flag == 3){ return test3(); }else if(flag == 4){ return test4(); }else if(flag == 5){ retrun test5(); ...... }else{ retrun test(); }
switch寫法
switch(flag){ case 1: retrun test1(); break; case 2: retrun test2(); break; case 3: retrun test3(); break; case 4: retrun test4(); break; case 5: retrun test5(); break; ...... default: retrun test(); break; }
上述語句均可以簡寫爲:
let caseList = {1: test1, 2: test2, 3: test3, 4: test4, 5: test5 ......}; if(flag && flag in caseList){ return caseList[flag] (); //此處爲了markdown正常顯示,多打了一個空格 } else { retrun test(); }
某些狀況下咱們須要循環進行異步處理,不少人這樣寫:
for(let n in obj){ await this.model.where({id: obj[n]['id']}).update({status: 1}); }
在併發量大或者數據庫數據量大的狀況下,理論上的處理時間和爲 (單個異步處理時間 * obj.length),會出現性能問題,推薦的寫法是:
let ps = []; for(let n in obj){ ps.push(this.model.where({id: obj[n]['id']}).update({status: 1}));//將異步事件放入數組 } await Promise.all(ps);//並行處理
理論上處理時間和爲 max(每一個異步處理時間)
無依賴是指,下次循環不須要依賴當前循環的異步事件結果。若是有依賴此方法不適用
一個例子:
let a = {"n" : 1}; let b = a; a.x = a = {"n": 2}; console.log(a.x);//undefined console.log(b.x);//{"n": 2}
乍一看,很容易弄錯結果,覺得a.x的值是{「n」: 2};其實否則,由於.運算符比賦值運算符優先級高,因此a.x賦值後,a再次賦值,指針變化了,a.x屬性丟失
推薦寫法:
let a = {"n" : 1}; let b = a; a.x = {"n": 2}; a = {"n": 2}; //此處明顯看出a的指針變化,x屬性丟失 console.log(a.x);//undefined console.log(b.x);//{"n": 2}
錯誤代碼:
return promise.then(data => { let info = await this.model.find(); //錯誤 ... });
正確代碼:
return promise.then(data => { return this.model.find(); }).then(info => { ... });
M('').query('select * from test'); //僅適用於mysql
mongoDb不能使用空模型,必須有對應的實體類:
M('Test').query('db.test.findOne()');
錯誤代碼:
if(true){ await this.model.where({id:1}).update({name: 'test'}); } return super.indexAction();//此處使用到了super調用父類方法,但在上面的語句中使用了await,被babel編譯以後,致使做用域混亂,控制器實例化失敗
正確代碼:
let promise = getPromise(); if(true){ promise = this.model.where({id: 1}).update({name: 'test'}); } return promise.then(() => { return super.indexAction();//注意此處的super在箭頭函數內,綁定的做用域爲控制器 });
錯誤代碼2:
await super.test(); //await被babel編譯後成爲Generator函數,在函數體內調用super致使做用域混亂 return this.render();
正確代碼2:
return super.test().then(() => this.render());
extend函數是ThinkNode框架提供的一個很是有用的函數,來自於jQuery。能夠實現對象和數組的繼承和克隆。可是在使用中必定要注意淺繼承和深繼承的區別。
淺繼承舉例:
let data = {"aa": {"qq": 555555}}; let temp = extend(false, {}, data);//第一個參數爲false,淺繼承 temp.aa.qq = 222222; console.log(data); //{ aa: { qq: 222222 } } //原始對象data被污染 console.log(temp); //{ aa: { qq: 222222 } }
深繼承舉例:
let data = {"aa": {"qq": 555555}}; let temp2 = extend({}, data); //深繼承 temp2.aa.qq = 222222; console.log(data); //{ aa: { qq: 555555 } } //原始對象未被污染 console.log(temp2); //{ aa: { qq: 222222 } }
區別是淺繼承僅僅複製了父對象的屬性值(基礎數據類型),若是父對象的屬性值爲一個對象(或數組),僅僅是賦值(指針指向)而非複製;