ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript はすべてのルールを破ります

JavaScript はすべてのルールを破ります

高洛峰
高洛峰オリジナル
2016-11-26 14:32:331448ブラウズ

Twitter のフロントエンド エンジニアであるアンガス クロール氏は、ベルリンで開催された JSConf カンファレンスで「すべてのルールを打ち破る」と題した講演を行いました。主に、私たちが通常間違っている、使用すべきではないと考えているものの、実際には役立ついくつかのことについて話します。米国のJavaScriptの父であるアンガス・クロール氏が講演に使用した講義ノート(リンク)を読んだところ、ほとんどの意見に同意しました(まだ問題はあるようですね?)。
これ以上の説明はせずに、以下の重要なポイントを簡単に翻訳します。

ステートメント付き
なぜそれを使用しないのですか?
1. 予期しない実行結果、グローバル変数が暗黙的に作成される可能性があります
2. コンパイル後のクロージャスコープの解決に消費されすぎる
ES5 の厳密モードにより暗黙的にグローバル変数が作成されるのを防ぐことができると言う人もいます。変数 (var を使用せずに) を使用すると、with の問題を軽減できます。しかし...
厳密モードでは with を使用できません。
なぜ便利ですか?
1. ブラウザー開発者ツールを構築します

// Chrome Developer Tools
IS。 _Evaluateon =
Function (EvalFunction, Obj, Expression) {
is._ensureCommandLineapIINSTALLED (); w._inSpectorCommandlineapi) {
With (Window) {" + Expression +"}} ";
Return evalFunction.call(obj,expression);
}
2. ブロックレベルのスコープをシミュレートします

//はい、これはまだ古い問題です
var addHandlers = function(nodes) {
for (var i = 0; i ノード[i].onclick =
function(e) {alert(i);}
}
};

//
var addHandlers = function(nodes) {
for (var i) の外側で関数をラップすることで解決できます= 0; i ノード[i].onclick = function(i) {
return function(e) {alert(i );};
}(i);
}
} ;

//または、ブロック レベルのスコープをシミュレートするには 'with' を使用します
var addHandlers = function(nodes) {
for (var i = 0; i with ({i:i }) {
nodes[i].onclick =
function(e) {alert(i);}
}
}
};
eval ステートメント
それを使用してみませんか?
1. コード インジェクション
2 を実行できません。クロージャーの最適化
3. コンパイル後の処理
なぜ便利ですか?
1. JSON.parse が利用できない場合
スタック オーバーフローで誰かが言いました:
「JavaScript の eval は安全ではないので、JSON を解析するには json.org の JSON パーサーを使用してください」
「JSON の解析に eval を使用しないでください! Douglas が書いた json2.js を使用してください!」という人もいます。
しかし:

/ / 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))
})()

function eval() {
[ネイティブコード]
}
John Resig 氏は次のように述べています:
「eval と with は軽蔑され、誤用されています。ほとんどの JavaScript プログラマーによって公然と非難されていますが、正しく使用すれば、他の関数では実装できない素晴らしいコードを書くことができます。
関数コンストラクター
なぜ役に立つのですか?
1. コードは予見可能な範囲内で実行されます
2. グローバル変数は動的にのみ作成できます
3. クロージャーはありません
パッケージの最適化の問題はどこで使用されますか?
// jQuery parseJSON

// ロジックは http://json から借用しました。 org/json2.js
if (rvalidchars.test(data.replace(rvalidescape,"@")
.replace( rvalidtokens,"]")
.replace( rvalidbraces,""))) {

return ( new Function ( "return " + data ) )();
}
2. Underscore.js
の文字列補間
//from _.template

// 変数が指定されていない場合は、
//にデータ値を配置しますローカルスコープ.
if (!settings.variable)
source = 'with(obj||{}){n' + source + '}n';

//..

var render = new Function(
settings .variable || 'obj', '_', source) ;
== 演算子
これを使用しないのはなぜですか?
1. 両側のオペランドを強制的に同じ型に変換します
なぜ便利ですか?
1.両辺のオペランドを強制的に同じ型に変換する
2. unknown == null

//こう書くと面倒じゃないですか
if ((x === null) || (x == = unknown))

//次のように書くことができます
if (x == null )
3. 両側のオペランドの型が明らかに同じ場合に使用します

typeof thing == "function"; typeof 演算子は必ず文字列を返します
myArray.length == 2; //length 属性は必ず数値を返します
myString .indexOf('x') == 0; //indeOf メソッドは必ず数値を返します
True値は必ずしも ==true であるとは限りません、false 値は必ずしも ==false であるとは限りません

if ("potato") {
"potato" == true ; //false
}
配列コンストラクター
なぜ使わないのですか?
1.new Array() も邪悪ですか? JSLint も [] の使用を推奨しています。
なぜ便利ですか?
//prototype.js の拡張子から
//String.prototype
function 回 (count) ) {
return count < 1 ?
'' : new Array(count + 1).join(this);
}
'me'.times(10); //"memememememememe"
Others
No ネイティブを拡張しますプロトタイプオブジェクト
(ES 5 shimsはすべてこれを行います)
for/inトラバーサルのときは常にhasOwnPropertyを使用してください
(オブジェクトプロトタイプを拡張せずにこれを行う必要はありません)
すべてのvarステートメントを先頭に置きます
(
初期化式のfor文)
関数を呼び出す前に関数を宣言
(実装内容を優先する場合に使用)
カンマ演算子は使用しない
(複数の式を使用する場合に使用可能)
第2引数は必ず次のように指定するparseInt を使用する場合は 10 です
(文字列が '0' または 'x' で始まらない限り、これは必要ありません)
翻訳者注
以上述べましたが、私も自分で考えました 誤解されているのはエスケープです。インターネット上の人々は、「エスケープを使用しないでください」と言っています。
なぜそれが便利だと言われているのですか?
1. エスケープはより多くの文字をエスケープし、場合によっては最後の 2 つの関数はエスケープされていない文字をエスケープする必要があります。
ASCII char エスケープ( ) encodeURI() encodeURIComponent()
! !
# %23 # %23
$ %24 $ %24
& %26 & %26
' ' '
( %28 ( (
) %29 ) )
+ + + %2B
, %2C , %2C
/ / / / %2F
: %3A
; %3B
= %3D
?
@ @ @ %40
~ %7E ~ ~
2. 文字列を UTF8 エンコードに変換します (通常は Base64 で使用されます)。
escape は utf16 でエンコードされた文字列に相当します。encodeURIComponent は utf16 文字列を utf8 エンコードに変換するのに相当します。最初にエスケープします。
encodeURIComponent(str) ===escape(UTF16ToUTF8(str))
UTF16ToUTF8(str) === unescape( encodeURIComponent (str)
その後、base64エンコーディングで使用できると推測できます。 btoa と atob には互換性の問題があることに注意してください。
return decodeURIComponent(escape(atob(str)));
}



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。