ECMAscript 5:厳密モード、JSONなど

ECMAScript 5のオブジェクトとプロパティの機能を分析していました。 これは言語の巨大な新しい側面であり、特別な考慮に値します。



他にも注意が必要な新しい機能とAPIがいくつかあります。 最も重要なのは、 厳格モードとネイティブJSONサポートです。



厳格モード



厳密モードはECMAScript 5の新機能で、プログラムまたは関数を「厳密な」操作コンテキストで強制的に実行できます。 厳密なコンテキストは、特定のアクションを実行する能力を妨げ、より多くの例外をスローします(また、ユーザーにより多くの情報を提供し、ピラミッドを下にしたコーディングパラダイムをサポートします)。



ECMAScript 5はECMAScript 3と下位互換性がありますが、現在「推奨」されていないECMAScript 3のすべての「機能」は、厳格モードで単純に無効(または例外をスロー)になります。



厳格モードは、一度にいくつかの側面で役立ちます。

厳格なモード情報のほとんどは、 ES5仕様[PDF]の 223ページにあります。



ストリクトモードECMAScript 5は、Firefoxで使用可能なストリクトモード(config:javascript.options.strictパラメーターについて有効にできる)とは異なることに注意してください。 ES5の厳格モードは、潜在的なエラーの完全に異なるセットをブロックします(既存のFirefoxの厳格モードは、適切なコードを記述するための推奨事項を順守しようとしますが、それ以上のことは行いません)。



厳格モードを有効にするにはどうすればよいですか?


シンプル。 このステートメントをプログラムの上に貼り付けて、スクリプト全体で有効にします。

"use strict" ;



* This source code was highlighted with Source Code Highlighter .








または、このステートメントを関数内に配置して、そのコンテキスト内でのみ厳密モードを有効にします。

function imStrict(){

"use strict" ;

// ... your code ...

}



* This source code was highlighted with Source Code Highlighter .








厳密モードを有効にするために使用される構文に注意してください(私は気に入っています!)。 これは、「use strict」という値を含む単一のステートメント文字列です。 厳格モードを定義するための新しい構文は導入されていません。 これは大きなプラスです。 これは、スクリプトで厳格モードを有効にできることを意味します-今日-最悪の場合、古いブラウザでは副作用がありません。



ここと前の記事の例からわかるように、ECMAScript 5仕様の言語には、新しい構文の追加や変更はほとんどありません。つまり、ES5スクリプトをレガシークライアント向けに正しく低下させることができるということです。これはECMAScript 4では不可能でした。厳密モードがサポートされる方法は、実際のこの点を鮮明に示しています。



また、関数内で厳格モードを定義することの気の利いた側面は、外部からのコードに影響を与えることなく、完全に厳格モードでJavaScriptライブラリを定義できることです。

// Non-strict code...



( function (){

"use strict" ;



// Define your library strictly...

})();



// Non-strict code...




* This source code was highlighted with Source Code Highlighter .






多くのライブラリはすでに前述の手法(ライブラリ全体を匿名関数でラップしてから実行)を使用しており、非常に簡単です。

厳格な体制を活用できるようになります。



スクリプトを厳格モードにすると、何が変わるのでしょうか? たくさん。



変数とプロパティ


foo = "bar";



を割り当てようとしfoo = "bar";



変数「foo」が定義されていない場合、失敗します。 以前は、このコードはグローバルオブジェクト(たとえば、window.foo)のfooプロパティに値を割り当てていましたが、現在は例外のみをスローします。 これにより、迷惑なエラーが確実に排除されます。



書き込み可能な属性がfalseに設定されているプロパティを変更したり、構成可能な属性がfalseに設定されているプロパティを削除したり、拡張可能な属性がfalseに設定されているオブジェクトにプロパティを追加しようとすると、誤って失敗します(これらの属性については前説明しました ) 通常モードでは、これらのアクションのいずれかが実行されてもエラーはスローされず、警告なしに失敗します。



変数、関数、またはパラメーターを削除するとエラーになります。



var foo = "test" ;

function test(){}



delete foo; // Error

delete test; // Error



function test2(arg) {

delete arg; // Error

}



* This source code was highlighted with Source Code Highlighter .






1つのオブジェクトリテラルでプロパティを複数回定義すると、例外がスローされます。

// Error

{ foo: true , foo: false }



* This source code was highlighted with Source Code Highlighter .








評価する


「eval」という名前を使用する試みはほとんど禁止されています。これは、eval関数をオブジェクトの変数またはプロパティに割り当てる機能です。

// All generate errors...

obj.eval = ...

obj.foo = eval;

var eval = ...;

for ( var eval in ... ) {}

function eval(){}

function test(eval){}

function (eval){}

new Function( "eval" )



* This source code was highlighted with Source Code Highlighter .








さらに、evalを介して新しい変数を導入する試みはブロックされます。

eval( "var a = false;" );

print( typeof a ); // undefined





* This source code was highlighted with Source Code Highlighter .








機能


引数オブジェクトを書き換えようとすると、エラーが発生します。

arguments = [...]; // not allowed



* This source code was highlighted with Source Code Highlighter .






同じ名前で複数の引数を定義するとエラーになります

function (Foo, Foo) {} // error



* This source code was highlighted with Source Code Highlighter .








arguments.callerおよびarguments.calleeにアクセスすると、例外がスローされるようになりました。 したがって、リンクする匿名関数には、たとえば次のように名前を付ける必要があります。

setTimeout( function later(){

// do stuff...

setTimeout( later, 1000 );

}, 1000 );




* This source code was highlighted with Source Code Highlighter .






他の関数の引数と呼び出し元のプロパティはもう存在しません-それらを定義する機能は禁止されています。

function test(){

function inner(){

// Don't exist, either

test.arguments = ...; // Error

inner.caller = ...; // Error

}

}



* This source code was highlighted with Source Code Highlighter .






最後に、長年の(そして非常に迷惑な)エラーが修正されました:nullまたはundefinedがグローバルオブジェクトになることを強制される場合。 厳密モードでは、これを防ぐことができ、代わりに例外がスローされます。

( function (){ ... }).call( null ); // Exception



* This source code was highlighted with Source Code Highlighter .








(){}


厳格モードでは、ステートメントはBoseに置かれます。実際、構文エラーのように見えます。 この演算子は確かに誤解されており、誤って使用されていた可能性があるという事実にもかかわらず、このような記録の影響を受けるのに十分かどうかはわかりません。



ECMAScript 5のストリクトモードで行われた変更は間違いなく変化します(文による削除などの文体的な設定の強制から、オブジェクトリテラルのプロパティをオーバーライドする機能など、言語の悪いエラーの修正まで)。 人々がこれらのイノベーションにどのように適応し始め、これらのイノベーションがJavaScriptの開発をどのように変えるかを見るのは興味深いでしょう。



jQueryがES5ストリクトモードと互換性を持つようになったことは間違いありません。 (このステートメントを検証できるように)この言語の実装が利用可能になり次第、jQueryを厳密モードでのみ動作するように喜んで切り替えます。




ジョンソン



この言語の2番目の重要な機能は、言語自体にネイティブJSONサポートが追加されていることです。



私はこのステップを長い間 主張してきましたが 、最終的に仕様でそれを見ることができてとてもうれしいです。



近い将来、JSONアプリケーションのCrockfordからjson2.jsへの移行を開始してください。 ECMAScript 5仕様と完全な互換性があり、ネイティブ(より高速!)実装が存在する場合はそれを適切に切り替えます。



実際、昨日jQueryの変更をコミットして、JSON.parseメソッドが存在する場合はそれを使用するようにしました。これで、このメソッドが最終的に指定されました。



JSONを処理するには、JSON.parse(JSON文字列をJavaScriptオブジェクトに変換する)とJSON.stringify(JavaScriptオブジェクトをシリアル化された文字列に変換する)の2つの主な方法があります。



JSON.parse(テキスト)


シリアル化されたJSON文字列をJavaScriptオブジェクトに変換します

var obj = JSON.parse( '{"name":"John"}' );

// Prints 'John'

print( obj.name );




* This source code was highlighted with Source Code Highlighter .








JSON.parse(テキスト、翻訳)


変換機能を使用して値を変換するか、値を完全に削除します。

function translate(key, value) {

if ( key === "name" ) {

return value + " Resig" ;

}

}



var obj = JSON.parse( '{"name":"John","last":"Resig"}' , translate);

// Prints 'John Resig'

print( obj.name );



// Undefined

print( obj.last );



* This source code was highlighted with Source Code Highlighter .








JSON.stringify(obj)


JavaScriptオブジェクトをシリアル化された文字列に変換します

var str = JSON.stringify({ name: "John" });

// Prints {"name":"John"}

print( str );




* This source code was highlighted with Source Code Highlighter .








JSON.stringify(obj、["white"、 "list"])


指定されたプロパティの「ホワイトリスト」のみをシリアル化します。

var list = [ "name" ];

var str = JSON.stringify({name: "John" , last: "Resig" }, list);

// Prints {"name":"John"}

print( str );




* This source code was highlighted with Source Code Highlighter .








JSON.stringify(obj、翻訳)


変換関数を使用してオブジェクトをシリアル化します。

function translate(key, value) {

if ( key === "name" ) {

return value + " Resig" ;

}

}



var str = JSON.stringify({ "name" : "John" , "last" : "Resig" }, translate);

// Prints {"name":"John Resig"}

print( str );



* This source code was highlighted with Source Code Highlighter .








JSON.stringify(obj、null、2)


指定した数のスペースを出力に均等に追加します。

var str = JSON.stringify({ name: "John" }, null , 2);

// Prints:

// {

// "name": "John"

// }

print( str );




* This source code was highlighted with Source Code Highlighter .








JSON.stringify(obj、null、「\ t」)


指定された文字列を使用してタブを実行します。

var str = JSON.stringify({ name: "John" }, null , "\t" );

// Prints:

// {\n\t"name": "John"\n}

print( str );




* This source code was highlighted with Source Code Highlighter .








また、いくつかの基本的なオブジェクトにいくつかの新しいユニバーサルメソッドが追加されましたが、心からはそれほど興味深いものではありません。 String、Boolean、およびNumberの結果はquery.valueOf()と同等であり、Dateの結果は.toISOString()の呼び出しと同等です。

// Yawn...

String.prototype.toJSON

Boolean.prototype.toJSON

Number.prototype.toJSON

Date.prototype.toJSON



* This source code was highlighted with Source Code Highlighter .








.bind()



言語への歓迎すべき追加機能は、関数コンテキストを実装するための組み込みの.bind()メソッドです(実際には、Prototype.jsライブラリーの.bind実装と同じです)。



Function.prototype.bind(thisArg、arg1、arg2 ....)


指定された関数の「this」値を指定されたオブジェクトに設定し、指定されたパラメーターを関数に渡します。

var obj = {

method: function (name){

this .name = name;

}

};



setTimeout( obj.method.bind(obj, "John" ), 100 );



* This source code was highlighted with Source Code Highlighter .






この関数(およびそれに相当するもの)がさまざまなライブラリに存在する期間を考えると、これは言語への歓迎すべき追加です。



日付



日付は、ISOフォーマットで解析および表示できるようになりました。 ありがとう



Dateコンストラクターは、ISO規格に従ってフォーマットされているかのように、最初に日付の分析を試み、その後、彼が理解する他の形式に進みます。



さらに、日付オブジェクトには新しい.toISOString()メソッドが追加され、日付をISO形式で表示します。

var date = new Date( "2009-05-21T16:06:05.000TZ" );



// Prints 2009-05-21T16:06:05.000TZ

print( date.toISOString() );



* This source code was highlighted with Source Code Highlighter .








.trim()



ネイティブの組み込み.trim()メソッドが文字列に含まれるようになりました。 他のすべてのトリムメソッドと同じように動作しますが、より高速に動作する可能性があります。



スティーブン・レビタンは、トリム方法についてさらに詳しく議論しまし



配列



JavaScript配列の拡張は最終的に正式に定義されたようです。 次のメソッドが含まれます:indexOf、lastIndexOf、every、some、forEach、map、filter、reduce、reduceRight。



さらに、新しいArray.isArrayメソッドが追加され、次の機能と非常によく似た機能が提供されます。

Array.isArray = function ( array ) {

return Object.prototype.toString.call( array ) === "[object Array]" ;

};




* This source code was highlighted with Source Code Highlighter .








全体として、ECMAScript 5は興味深い提案をしていると思います。 これはECMAScript 4が約束した大きな飛躍ではありませんが、明らかなエラーの数を減らし、言語をより安全かつ高速にする一連の素晴らしい機能強化です。 いくつかの実装が公開されるのを楽しみにしています。



All Articles