この記事では、ES6 の新しい変数宣言方法を紹介します (コード付き)。一定の参考値があります。困っている友人は参考にしてください。お役に立てれば幸いです。
ES5では変数宣言はvar、function、implicit宣言の3種類のみでしたが、ES6ではlet、const、import、classの4種類が追加されました。
1. let
1.1 ブロックレベルのスコープ
let で宣言された変数のスコープはブロックレベルのスコープです (この機能はバックエンド言語に似ています)、ES5 にはブロックレベルのスコープはなく、関数スコープとグローバル スコープのみがあります。
{ let a = 'ES6'; var b = 'ES5'; } console.log(b) // ES5 console.log(a) // ReferenceError: a is not defined.
それでは、ブロックレベルのスコープの利点は何でしょうか?
let は、for ループ内のブロックレベルのスコープに非常に適しています。 JS の for ループ本体は特別です。各実行は新しい独立したブロック スコープです。let で宣言された変数は for ループ本体のスコープに渡された後は変更されず、外部の影響も受けません。面接でよくある質問を見てください:
for (var i = 0; i <10; i++) { setTimeout(function() { // 同步注册回调函数到异步的宏任务队列。 console.log(i); // 执行此代码时,同步代码for循环已经执行完成 }, 0); } // 输出结果 10 (共10个) // 这里变量为i的for循环中,i是一个全局变量,在全局范围内都有效,所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮i的值,即i的最终结果为10,实际上都是console.log(10)。涉及的知识点:JS的事件循环机制,setTimeout的机制等
Change var to let ステートメント:
for (let i = 0; i < 10; i++) { setTimeout(function() { console.log(i); //当前的i仅在本轮的循环中有效,就是说每一次循环,i其实都是一个新产生的变量。 //用 let 声明的变量 i 只作用于循环体内部,不受外界干扰。 }, 0); } // 输出结果: 0 1 2 3 4 5 6 7 8 9
1.2 一時的なデッド ゾーン
ブロック レベルのスコープでは、変数はのみ存在します。変数がブロックレベルのスコープで let で宣言されている場合、変数はこのブロックレベルのスコープに一意に属し、以下に示すように外部変数の影響を受けません。
var tmp = 'bread and dream'; if(true){ tmp = 'dream or bread'; //ReferenceError let tmp; }
この例では、tmp = 'dream or bakery' の代入はエラーを報告します。これは、if ブロックで let が tmp 変数を宣言しており、tmp がこのスコープにバインドされ、一時的に終了するためです。 . そのため、宣言前では使用できないため、宣言前に変数に値を代入するとエラーとなります。
一時的なデッド ゾーンの本質は、現在のスコープに入るとすぐに、使用される変数はすでに存在しますが、取得できないということです。変数を宣言するコード行が表示された場合にのみ、変数を取得できるようになります。変数を取得して使用します。
一時的なデッド ゾーンの重要性は、コードを標準化し、すべての変数の宣言をスコープの先頭に配置できるようにすることでもあります。
1.3 繰り返しの宣言は許可されません
(1) 同じスコープ内で、let を使用して変数を宣言する場合、宣言は 1 回のみ許可されますが、var は複数回宣言できます。 。 ES5 で複数の宣言を行うと変数カバレッジが発生し、エラーが報告されないことは誰もが知っています。そのため、デバッグがより困難になりますが、クレードルではエラーが直接報告されるため、この問題を直接解決できます。
// 不报错 function demo() { var a = 'bread and dream'; var a = 'dream or bread'; } // 报错,Duplicate declaration "a" function demo() { let a = 'bread and dream'; var a = 'dream or bread'; } // 报错,Duplicate declaration "a" function demo() { let a = 'bread and dream'; let a = 'dream or bread'; }
(2) 関数内でパラメータを再宣言することはできません:
function demo1(arg) { let arg; // 报错 } demo1() function demo2(arg) { { let arg; // 不报错 } } demo2()
2. const
2.1 は定数の宣言に使用されます
const で宣言された定数は変更できず、読み取り専用の属性です。これは、定数が宣言されるときに値を割り当てる必要があることを意味します。割り当てなしで宣言された場合、エラーが報告されます。通常、定数には名前が付けられます大文字で。
const Person; // 错误,必须初始化 const Person = 'bread and dream';// 正确 const Person2 = 'no'; Person2 = 'dream or bread'; //报错,不能重新赋值
これには 2 つの利点があります。1 つ目は、コードを読む人がこの値を変更すべきではないことにすぐに気づくこと、2 つ目は、変数値を不注意に変更することによって引き起こされるエラーを防ぐことです。例えば、nodejsの一部のモジュールを使用する場合、該当するモジュール(httpモジュールなど)のみを使用しますが、nodejsモジュールを変更する必要はなく、この際constとして宣言することで可読性が向上します。コードを修正してエラーを回避します。
2.2 ブロック レベルのスコープをサポートします。
const は let に似ており、ブロック レベルのスコープもサポートします。
if (true) { const MIN = 5; } MIN // Uncaught ReferenceError: MIN is not defined
2.3 変数のプロモーションをサポートせず、一時的なデッド ゾーンがあります。
const によって宣言された定数は昇格されず、一時的なデッド ゾーンもあり、宣言された位置の後にのみ使用できます。
if (true) { console.log(MIN); // ReferenceError const MIN = 5; }
2.4 特殊なケース
宣言された定数がオブジェクトの場合、オブジェクト自体を再割り当てすることはできませんが、オブジェクトのプロパティを割り当てることはできます。
const obj = {}; obj.a = 'xiao hua'; console.log(obj.a); //'xiao hua'
実際、const が保証できるのは、変数の値が変更できないことではなく、変数が指すメモリ アドレスに格納されているデータが変更できないことです。
単純なタイプのデータ (数値、文字列、ブール値) の場合、値は変数が指すメモリ アドレスに格納されるため、定数と同等です。
ただし、複合型データ (主にオブジェクトと配列) の場合、変数が指すメモリ アドレスには実際のデータへのポインタのみが格納されます。
それが指すデータ構造が可変であるかどうかについては、完全に制御不能です。したがって、オブジェクトを定数として宣言するときは細心の注意を払う必要があります。
オブジェクトを完全にフリーズする (そのプロパティは変更できない) 場合は、Object.freeze(obj) メソッドを使用する必要があります。配列についても同様です。
3. import
ES6 では、モジュールをインポートするノードなどの require の代わりに import を使用します。
import {$} from './jquery.js'
$オブジェクトは、jquery のエクスポートによって公開されるオブジェクトです。
入力変数の名前を変更する場合は、インポート コマンドで as キーワードを使用して入力変数の名前を変更します。
import { JQ as $ } from './jquery.js';
import コマンドには昇格効果があり、モジュール全体の先頭に昇格して最初に実行されることに注意してください。
4. class
ES6 では、クラスの概念とキーワード class が導入されています。クラスの本質はやはり関数オブジェクトです。
最初にクラスを定義します:
//定义类 class Animal { constructor(name, age) { this.name = name; this.age = age; } setSex(_sex) { this.sex=_sex; } }
コンストラクターメソッドはES5時代の関数オブジェクトの本体となるコンストラクターメソッドで、thisキーワードはインスタンスオブジェクトを表します。
上記のクラスは、ES5 の記述に変更することもできます。
function Animal(name, age){ this.name = name; this.age = age; } Animal.prototype.setSex = function (_sex) { this.sex=_sex; }
実際、ほとんどのクラスの特性は、以前の関数オブジェクトとプロトタイプを通じて推測できます。
生成类的实例对象的写法,与ES5通过构造函数生成对象完全一样,也是使用new命令。
class Animal {} let dog = new Animal();
在类的实例上面调用方法,其实就是调用原型上的方法,因为类上的方法其实都是添加在原型上。
Class其实就是一个function,但是有一点不同,Class不存在变量提升,也就是说Class声明定义必须在使用之前。
5.总结
在ES6之前,JavaScript是没有块级作用域的,如果在块内使用var声明一个变量,它在代码块外面仍旧是可见的。ES6规范给开发者带来了块级作用域,let和const都添加了块级作用域,使得JS更严谨和规范。
let 与 const 相同点:
块级作用域
有暂时性死区
约束了变量提升
禁止重复声明变量
let 与 const不同点:
const声明的变量不能重新赋值,也是由于这个规则,const变量声明时必须初始化,不能留到以后赋值。
合理的使用ES6新的声明方式,不管是面试还是工作中都有实际的应用,尤其是工作中,大家一定要尽量的多使用新的声明方式,不但可以让代码更规范,更可以避免不必要的bug,浪费调试时间,进而提高工作效率。
本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!
以上がES6の新しい変数宣言方法の紹介(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。