首頁 > web前端 > js教程 > JavaScript打破所有規則

JavaScript打破所有規則

高洛峰
發布: 2016-11-26 14:32:33
原創
1444 人瀏覽過

來自Twitter的前端工程師Angus Croll,在柏林舉辦的JSConf會議上,進行了題為”Break all the Rulez“的演講。主要講了一些我們通常認為是錯誤的不該使用的東西,其實是有用的。 Angus Croll 演講用的講稿(連結),遠在美國的JavaScript之父看後也說同意其中大部分觀點(看來還是有問題?)。
下面我把要點簡單翻譯一下,不做擴展解釋.

with語句
為什麼不去使用它?
1.意外的運行結果,可能隱式創建全局變數
2.閉包作用域解析過多消耗
3.後期編譯
有人說,ES5的嚴格模式可以防止隱式創建全域變數(不用var),這樣能減少with的一個問題.但是…
嚴格模式也不能使用with啊.
為什麼說它是有用的?
1.構建瀏覽器開發者工具
 
// Chrome Developer Tools
IS._evaluateOn =
  function(evalFunction, obj, expression) {
    IS._ensureCommandLineAPIInstalled();       with (window) { " + expression + " } } ";
    return evalFunction.call(obj, expression);
}
2.模擬塊級作用域
 
//是的,還是這個老掉牙的問題 (var addHandlers = function(nodes) for
0; i     nodes[i].onclick =
      function(e) {alert(i);}
  }
};
 
var addHandlers = function(nodes) {
  for (var i = 0; i     nodes[i].onclick = function(i) {
    };
    }(i);
  }
};
 
//或使用'with'來模擬區塊級作用域
var addHandlers = function(nodes) {
  for (var i = 0. ; i++) {
    with ({i:i}) {
      nodes[i].onclick =
        function(e) {alert(i);}語句🎠 ?
1.程式碼注入
2.無法進行閉包最佳化
3.後期編譯
為什麼說它是有用的?
1. JSON.parse不可用的時候
有人在Stack Overflow上說:
「JavaScript的eval是不安全的,使用json.org上的JSON解析器來解析JSON”
還有人說:
“不要使用eval來解析JSON!用道格拉斯寫的json2.js!”
可是:
 
// From JSON2 .js
 
if (/^[],:{}s]*$/
  .test(text.replace(/*regEx*/, '@')
  .replace(/*regEx*/, ']' )
  .replace(/*regEx*/, ''))) {
  j = eval('(' + text + ')');
}
2.瀏覽器的JavaScript控制台都是用eval實現的
在Webkit控制台或JSBin中執行下面的程式碼
 
>(function () {
    console.log(String(arguments.callee.caller))
})()
ative ]
}
John Resig說過:
「eval和with是被輕視的,被誤用的,被大部分JavaScript程式設計師公然譴責的,但如果能正確使用的話,可以用它們寫出一些奇妙的,無法用其他功能實現的程式碼」
Function建構子
為什麼說它是有用的?
1.程式碼運行在可預見的作用域內
2.只能動態建立全域變數
3.不存在閉包最佳化的問題
用在什麼地方?
1. jQuery的parseJSON
 
// jQuery parseJSON
 
// Logic borrowed from http://json.org/json2.jso.testif (rdataidplaces.testif(rdata.charot( "@")
  .replace( rvalidtokens,"]")
  .replace( rvalidbraces,""))) {
 
  return ( new Function( "return " + data ) )();
  return ( new Function( "return " + data ) )(); js的字串內插
 
//from _.template
 
// If a variable is not specified,
// place data values in local scope.
if (!sperings.variable)_obings. ||{}){n' + source + '}n';
 
//..
 
var render = new Function(
  settings.variable || 'obj', '_', source);
==運算子
為什麼不去使用它?
1.強制將兩邊的操作數轉換為相同類型
為什麼說它是有用的?
1.強制將兩邊的操作數轉換為相同類型
2.undefined == null
 
//這樣寫是不是很麻煩
if ((x === null) || (x === undefined))
 
//完全可以下面這樣寫
if (x == null)
3.當兩邊的操作數類型明顯相同時使用
 
typeof thing == "function";   //typeof運算子肯定回傳字串
myArray.length == 2;         x') == 0;   //indeOf方法肯定回傳數字
真值不一定==true,假值不一定==false
 
if ("potato") {
  "potato" == true;  //false
}
Array建構子
為什麼不使用它?
1.new Array()也是evil的?JSLint也推薦使用[].
為什麼說它是有用的?
 
//From prototype.js extension of
//String.prototype
function times(count) {
  return count     '' : new Array(count + 1).join(this);
}
'me'.times(10); //"mememememememememe}
'me'.times(10); //"mememememememememeemeeme"
原生的原型物件
(es 5 shims都這樣乾)
在for/in遍歷時總要使用hasOwnProperty
(在沒有擴展對象原型的前提下沒有必要這麼做)
把所有的var語句放在頂部
( for語句還是放在初始化表達式中好)
要在呼叫函數之前先宣告函數
(在優先考慮實作細節時使用)
不要使用逗號運算子
(在使用多個表達式時的時候可以使用)
使用parseInt時總是要把第二個參數指定為10
(除非字串以'0'或'x'開頭,否則沒必要)
譯者註
上面說了這麼多,我自己也想到一個被誤解的東西,那就是escape.網上有不少人說:“不要使用escape”.
為什麼說它是有用的?
1.escape轉義的字符更多,有時候需要轉義後兩個函數不轉義的字元.
ASCII char escape() encodeURI() encodeURIComponent()
! %21 ! !
# %23 #  '
( %28 ( (
) %29 ) )
+ + + %2B
, %2C , %2C
/ / / %2F🠎3%F%2C🠎 
= %3D = %3D
? %3F ? %3F
@ @ @ %40
~ %7E ~ ~
2.將字串轉換為UTF8編碼,通常用在base64的時候.
escape轉義,encodeURIComponent相當於是先把utf16的字串轉換成utf8編碼後再escape.
encodeURIComponent(str) === escape(UTF16ToUTF8(str))
可以推導出UTF16ToUTF8(str) === RIscape(str. str )
接著就能用在base64編碼的時候,比網上看到的那些簡單多了吧.注意btoa和atob有兼容問題.
 
function base64Encode(str) {
    return btoa(strscape(encodeURIon(strscape(encodeU) ));
}
 
function base64Decode(str) {
    return decodeURIComponent(escape(atob(str)));
}



相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板