ブロックレベルの範囲
ES5にはブロックレベルの範囲はなく、グローバルスコープと関数スコープのみがあります。このため、変数の範囲は非常に広いため、関数を入力するとすぐに作成する必要があります。これにより、いわゆる変数が増加します。
ES5の「変数改善」機能は、注意しないとエラーを引き起こすことがよくあります。
1.内側の変数は外側の変数をカバーします
var tmp = new date(); function f(){console.log(tmp); if(false){// undefinedvar tmp = "hello world";}}を実行2。変数がグローバル変数に漏れます
var s = 'hello'; for(var i = 0; i <s.length; i ++){console.log(s [i]);} console.log(i); // 5過去には、閉鎖を使用してこの問題を解決するために(自己実行機能など)。現在、この問題に基づいて、ES6はブロックレベルの範囲を追加しているため、単独で関数を実行する必要はありません。
letとconst
ES6は後方互換性があり、逆方向の互換性を維持することは、Webプラットフォーム上のJSコードの動作を決して変更しないため、VARによって作成された変数の範囲はグローバルな範囲と機能範囲になります。このようにして、ブロックレベルの範囲がある場合でも、ES5の「変動改善」問題を解決することはできません。したがって、ここでES6は2つの新しいキーワードを追加しました:letとconst。
1.LET
「レットはより完璧なvarです」、それはより良いスコープルールを持っています。
2.CONST
constは読み取り専用定数を宣言します。宣言されると、定数の値を変更することはできませんが、constによって宣言されたオブジェクトにはプロパティの変更があります(オブジェクトフリーズオブジェクト。フリーズ)
const a = []; a.push( 'hello'); //実行可能a = ['dave']; //エラーを報告します
Object.Freezeを使用してオブジェクトをフリーズすることもできます
const foo = object.freeze({}); //通常モードでは、次の行が機能しません。 //厳密なモードでは、行はエラーfoo.prop = 123; //を報告しますletとconstを使用してください:
•変数は、宣言が配置されているブロックレベルの範囲内でのみ有効です
•可変宣言は使用することができます(一時的なデッドゾーン)
•変数を繰り返し定義することはできません
•宣言されたグローバル変数、グローバルオブジェクトに属さない属性
var a = 1; window.a // 1let b = 1; window.b //未定義
このキーワード
ES5関数のこれは、ランタイムが配置されているスコープを指していることを知っています。例えば
function foo(){settimeout(function(){console.log( 'id:'、this.id);}、100);} var id = 21; foo.call({id:42}); // id:21ここでは、内部的に遅延関数のsetimeoutである関数fooを宣言し、100msごとにthis.idを印刷します。 foo.call({id:42})を介してそれを呼び出し、この関数のスコープを設定します。実際に実行するには100ミリ秒かかります。これは、ランタイムが配置されているスコープを指しているため、ここでは関数fooではなく、グローバルオブジェクトウィンドウを指します。ここ:
•CALLを使用してFOOの実行コンテキストを変更して、このポインターをSettimeOutで区別するために、関数の実行コンテキストがウィンドウにならないようにします。
•SettimeOutメソッドはウィンドウオブジェクトの下に掛けられているため、実行の範囲(ウィンドウオブジェクト)を指します。
タイムアウトと呼ばれるコードはグローバルスコープで実行されるため、関数のこの値は非強制モードでウィンドウオブジェクトを指し、厳密なモードで未定義です-《JavaScript Advanced Programming
この問題を解決するために、私たちの通常の練習は、これを他の変数に割り当てることです。
function foo(){var that = this; setimeout(function(){console.log( 'id:'、that.id);}、100);} var id = 21; foo.call({id:42}); // id:42現在、ES6はこの問題を解決するために矢印関数を起動しました。
矢印関数
識別子=>式
var sum =(num1、num2)=> {num1 + num2を返します。 } // var sum = function(num1、num2)に相当する{return num1 + num2;};•関数にパラメーターが1つしかない場合、括弧は省略できます
•関数に1つの返品ステートメントしかない場合、ブレースとリターンを省略できます
•関数がオブジェクトを直接返す場合、オブジェクトの外側に括弧を追加する必要があります。 (空のオブジェクト{}と空のブロック{}がまったく同じように見えるためです。したがって、オブジェクトリテラルをブラケットにラップする必要があります。)
このキーワードの問題に応じて、ES6は、ランタイムが配置されているスコープを指すのではなく、このバインディングが矢印関数で定義されるスコープを指定します。この点以来、この点は修正されており、コールバック関数のカプセル化を助長しています。
function foo(){var this = this; setimeout(()=> {console.log( 'id:'、that.id);}、100);} var id = 21; foo.call({id:42}); // id:42注:矢印関数を指す固定は、これを矢印関数内に結合するメカニズムがあるためではありません。実際の理由は、矢印関数がこれをまったく持っていないことです。矢印関数にはこれがまったくありません。内部はこれを外側のコードブロックにあります。これは次のとおりです。
•コンストラクターとして使用できません
•call()、apply()、bind()、およびその他の方法を使用して、この方向を変更することはできません
クラスと継承
従来のECMAScriptにはクラスの概念がありません。プロトタイプチェーンの概念を説明し、プロトタイプチェーンを継承を実装する主な方法として使用します。基本的なアイデアは、プロトタイプを使用して、1つの参照タイプが別の参照タイプのプロパティと方法を継承できるようにすることです。この動作を達成するための従来の方法は、コンストラクターを使用することです。
function point(x、y){this.x = x; this.y = y;} point.prototype.tostring = function(){return '(' + this.x + '、' + this.y + ')';}; var p = new Point(1、2);ここでは、コンストラクターポイントにはプロトタイプオブジェクト(プロトタイプ)があり、ポイントへのポインター(コンストラクター)が含まれ、インスタンスPにはプロトタイプオブジェクト(PROP)への内部ポインターが含まれます。したがって、継承全体がプロトタイプチェーンを介して実装されます。詳細については、JavaScriptのプロトタイプとコンストラクターのこの記事を参照してください
クラス
ES6は、従来の言語に近い執筆スタイルを提供し、クラスの概念をオブジェクトのテンプレートとして紹介します。クラスキーワードを使用して、クラスを定義できます。しかし、クラスは、プロトタイプベースのオブジェクト指向パターンの構文砂糖です。クラスの導入についてさまざまなレビューがあり、多くの人はそれが大きな欠陥だと考えていますが、私にとっては、プロトタイプチェーンを継承する通常の方法がしばらく私を包むことができるため、それは良い構文糖です。
// classクラスポイントを定義{constructor(x、y){this.x = x; this.y = y;} toString(){return '(' + this.x + '、' + this.y + ')';}} var p = new Point(1、2);•クラスにはコンストラクターメソッドがあり、クラスのデフォルトメソッドです。このメソッドは、新しいコマンドを介してオブジェクトインスタンスを生成するときに自動的に呼び出されます。クラスにはコンストラクターメソッドが必要です。明示的に定義されていない場合、デフォルトで空のコンストラクターメソッドが追加されます。
•コンストラクターメソッドのこのキーワードは、インスタンスオブジェクトを表します。
•「クラス」の方法(上記の例のトストリングなど)を定義する場合、キーワード関数を前に追加する必要はありません。関数定義を入力するだけです。さらに、メソッド間にコンマの分離はありません。
•それを使用する場合、クラスで新しいコマンドを直接使用します。これは、コンストラクターの使用とまったく同じです。
•クラスのすべての方法は、クラスのプロトタイププロパティで定義されています
クラスの継承 - 拡張
クラス間の継承は、拡張キーワードを介して達成できます。キーワードは、プロトタイプチェーンを変更することにより、ES5の継承よりもはるかに明確で便利です。
クラスのカラーポイントはextends point {constructor(x、y、color){super(x、y); //親クラス(x、y)this.color = color;} toString(){return this.color + '' + super.toString(); //親クラスのtoString()を呼び出す}}•スーパーキーワードは、関数として呼ばれる場合(つまり、スーパー(... args))、親クラスのコンストラクターを表します。オブジェクトとして呼ばれる場合(つまり、super.propまたはsuper.method())、親クラスを表します。ここでは、親クラスのコンストラクターを表し、親クラスのこのオブジェクトを作成するために使用されます。
•サブクラスはコンストラクターメソッドのスーパーメソッドを呼び出す必要があります。そうしないと、新しいインスタンスを作成するときにエラーが報告されます。これは、サブクラスに独自のオブジェクトがないが、親クラスのこのオブジェクトを継承してから処理するためです。スーパーメソッドが呼び出されない場合、サブクラスはこのオブジェクトを取得しません。
モジュラー
歴史的に、JavaScriptはモジュールシステムを持っていなかったため、大規模なプログラムを小さな相互依存ファイルに分割してから簡単な方法で組み立てることは不可能です。これにより、大規模で複雑なプロジェクトの開発に対する大きな障害が生まれました。大規模なモジュールの開発に適応するために、コミュニティはCMDやAMDなどのいくつかのモジュール負荷ソリューションを策定しました。
ES6のモジュラーライティング:
{fs 'から{stat、existes、readfile}をimport;上記のコードの本質は、FSモジュールから3つのメソッドをロードすることであり、他のメソッドはロードされません。この種の読み込みは「コンパイルタイムロード」と呼ばれます。つまり、ES6はコンパイル時間でモジュールの読み込みを完了できます。これは、CommonJSモジュールの読み込み方法よりも効率的です。もちろん、これはオブジェクトではないため、ES6モジュール自体を参照できないことにもつながります。
モジュール関数は、主に2つのコマンドで構成されています。
•輸出
モジュールと外部インターフェイスを指定するために使用される外部インターフェイスは、モジュール内の変数と1対1の対応関係を確立する必要があります。
// 1つのエクスポートvar m = 1; //エラーエクスポート1; //書き込み方法2 var m = 1; export {m}; //エラーエクスポートm; //書き込み方法•輸入
他のモジュールが提供する関数を入力するために使用されます。他のモジュールからインポートする変数名を指定するオブジェクト(ブレースで表される)を受け入れます(合計で *を使用してロードすることもできます)
文字列補間
JavaScript開発では、このようなテンプレートを出力する必要があることがよくあります。
function sayshello(name){return "hello、my name is"+name+"i am"+getage(18);} function getage(age){return age;} sayhello( "brand")// "こんにちは、私の名前はブランドです。+を使用して、文字列と変数(または式)を連結する必要があります。例は比較的単純なので、無害に見えますが、一度複雑になると、非常に面倒で不便に見えます。この点で、ES6はテンプレート文字列を導入します。これにより、JS値を文字列に簡単かつ優雅に挿入できます。
テンプレート文字列
テンプレート文字列の場合、それ:
•バックテックをパックします ``;
•$ {}を使用して値を出力します。
•$ {}のコンテンツは任意のJavaScript式になる可能性があるため、関数呼び出しと算術操作は合法です。
•値が文字列ではない場合、文字列に変換されます。
•すべてのスペース、ニューライン、インデントを保持し、結果文字列に出力します(複数行文字列を書き込むことができます)
•内部的にバックテックとブレースを使用して逃げ出し、バックスラッシュを使用します/
上記の例では、テンプレート文字列は次のように記述されています。
function sayshello(name){return `hello、私の名前は$ {name} i am $ {getage(18)}`;} function getage(age){return age;} sayhello( "brand")// "こんにちは、私の名前はBrandi am 18"厳密なモード
厳密なモードの目標の1つは、エラーのデバッグをより速くできることです。開発者のデバッグを支援する最良の方法は、静かに失敗したり、奇妙な動作を表示するのではなく、特定のパターンが発生したときにエラーをスローすることです(しばしば非厳格なモードで発生します)。 Strictモードのコードは、より多くのエラーメッセージをスローするため、開発者はすぐに解決する必要があるいくつかの問題にすぐに気付くことができます。 ES5では、Strict Modeはオプションですが、ES6では、多くの機能がStrictモードを使用する必要があるため、より良いJavaScriptの書き込みに役立ちます。
上記は、編集者が紹介したES6の改善JavaScriptの「欠陥」の問題です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!