検索
ホームページウェブフロントエンドjsチュートリアルECMAScript6変数の構造化代入の詳細説明

ES6 では、配列やオブジェクトから値を抽出し、特定のパターンに従って変数に値を割り当てることができます。これは構造化と呼ばれます。この記事では主に、入れ子になった配列の構造化の例を説明します。 , c] = [1, 2, 3];

この書き方は、等号の両側のパターンが同じであれば、左側の変数が代入されます。対応する値。

以下はネストされた配列を使用した構造化の例です

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

構造化が失敗した場合、変数の値は未定義と等しくなります

fooは未定義と等しくなります

var [foo] = [];
var [bar, foo] = [1];

不完全な構造化とは、上のパターンのみを意味します等号の左側が一致します 等号の右側の配列の一部

let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

等号の右側が配列でない場合、エラーが報告されます。

// 报错let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

分割代入はvarコマンドだけでなくletコマンドやconstコマンドにも適用できます

var [v1, v2, ..., vN ] = array;
let [v1, v2, ..., vN ] = array;
const [v1, v2, ..., vN ] = array;

Set構造体の場合、配列の分割代入も使用できます。

let [x, y, z] = new Set(["a", "b", "c"]);
x // "a"

特定のデータ構造が Iterator インターフェースを持つ限り、配列形式での分割代入が使用できます。

function* fibs() {
  var a = 0;
  var b = 1;
  while (true) {
  yield a;
   [a, b] = [b, a + b];
  }
}
var [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5

fibs はネイティブに Iterator インターフェースを持つ Generator 関数です。代入を分割すると、このインターフェイスから値が取得されます

代入を分割すると、デフォルト値を指定できます。

var [foo = true] = [];
foo // true
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'

ES6 は内部的に厳密等価演算子 ( === ) を使用して、位置に値があるかどうかを判断します。したがって、配列メンバーが undefined と厳密に等しくない場合、デフォルト値は有効になりません。

var [x = 1] = [undefined];
x // 1
var [x = 1] = [null];
x // null

配列メンバーが null の場合、null は厳密には unknown と等しくないため、デフォルト値は有効になりません

function f() {
console.log('aaa');
}
let [x = f()] = [1];
//等价于
let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}

デフォルト値が式の場合、式は遅延評価されます。使用時期 いつ評価されるか

デフォルト値は、分割代入の他の変数を参照できますが、その変数は宣言されている必要があります

let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError

なぜなら、xがデフォルト値yを使用するとき、yはまだ宣言されていないからです

分割代入オブジェクトの

var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

配列の要素は順番に配置され、変数の値はその位置によって決まりますが、オブジェクトの属性には順序がありません。変数には取得する属性と同じ名前が必要です。正しい値

var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

実際、オブジェクトの分割代入は次のとおりです。形式の略称

var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

オブジェクトの分割と代入の内部メカニズムは、最初に同じ名前の属性を見つけてから、それを対応する変数。実際に代入されるのは前者ではなく後者です

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

上記のコードでは、実際に代入されるのはモードfooではなく変数bazです

変数の宣言と代入は一体化されています。 let と const の場合、変数は再宣言できないため、割り当てられた変数が以前に宣言されている場合は、エラーが報告されます

let foo;
let {foo} = {foo: 1}; 
// SyntaxError: Duplicate declaration "foo"
let baz;
let {bar: baz} = {bar: 1}; 
// SyntaxError: Duplicate declaration "baz"
var コマンドでは再宣言が許可されているため、このエラーは let と const コマンドを使用する場合にのみ表示されます。 2 番目の let コマンドがない場合、上記のコードはエラーを報告しません

let foo;
({foo} = {foo: 1}); // 成功
let baz;
({bar: baz} = {bar: 1}); // 成功
配列と同様、構造の分割は入れ子構造を持つオブジェクトにも使用できます

var obj = {
  p: [
   "Hello",
   { y: "World" }
  ]
};
var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
このとき、p は変数ではなくパターンであるため、値は代入されません

var node = {
  loc: {
   start: {
     line: 1,
     column: 5
   }
  }
};
var { loc: { start: { line }} } = node;
line // 1
loc // error: loc is undefined
start // error: start is undefined
line のみが変数、loc と start はどちらもパターンで代入されません

ネストされた代入の例。

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123}
arr // [true]
オブジェクトの分割では、デフォルト値も指定されます

var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var { message: msg = "Something went wrong" } = {};
msg // "Something went wrong"
デフォルト値が有効になる条件は、オブジェクトの属性値が厳密に未定義に等しいことです

var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null
分割が失敗した場合、変数は未定義に等しい

var {foo} = {bar: 'baz'};
foo // undefined
分割モードはネストされたオブジェクトであり、子オブジェクトが配置されている親属性が存在しない場合、エラーが報告されます

// 报错
var {foo: {bar}} = {baz: 'baz'};
の左側のオブジェクトの foo 属性等号は子オブジェクトに対応します。このサブオブジェクトの bar 属性は、構造化時にエラーを報告します。この時点では foo は unknown に等しいため、サブプロパティを再度取得するとエラーが報告されます

宣言された変数を代入の構造化に使用したい場合は、細心の注意を払う必要があります

// 错误的写法
var x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正确的写法
({x} = {x: 1});
JavaScript エンジンが{x} をコード ブロックとして理解すると、文法エラーが発生します。この問題は、JavaScript がコード ブロックとして解釈しないように、行の先頭に中括弧を書かないことによってのみ解決できます

オブジェクトの分割代入により、既存のオブジェクトのメソッドを変数に簡単に割り当てることができます

let { log, sin, cos } = Math;
Math オブジェクトの log、sine、cosine メソッドが対応する変数に割り当てられるため、より使いやすくなります。

文字列の分解と代入

文字列を分解して代入することもできます。このとき、文字列は配列状のオブジェクトに変換されます

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
配列状のオブジェクトにはlength属性があるので、この属性も分解して代入することができます

let {length : len} = 'hello';
len // 5
数値やブール値の分解と代入

代入すると、等号の右側が数値またはブール値の場合、最初にオブジェクトに変換されます

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
数値とブール値のパッケージングオブジェクトはtoString属性を持っているので、変数 s は値を取得できます

分割代入のルールは、等号の右側が値である限り、値がオブジェクトではないため、最初にオブジェクトに変換することです。 unfineed や null はオブジェクトに変換できないため、分解して代入するとエラーとなります。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
関数パラメータの分割代入

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3
関数パラメータの分割はデフォルト値も使用可能

function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
関数moveのパラメータはオブジェクトであり、このオブジェクトを分割することで変数xとyの値が得られます。構造化が失敗した場合、x と y はデフォルト値と等しくなります。

function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
は変数 x と y のデフォルト値を指定するのではなく、関数 move のパラメータのデフォルト値を指定するため、別の値が得られます。以前の書き方より結果が変わりました。未定義は関数パラメータのデフォルト値をトリガーします

括弧の問題

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道如果模式中出现圆括号怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号

不能使用圆括号的情况

1.变量声明语句中,不能带有圆括号

// 全部报错
var [(a)] = [1];
var {x: (c)} = {};
var ({x: c}) = {};
var {(x: c)} = {};
var {(x): c} = {};}
var { o: ({ p: p }) } = { o: { p: 2 } };

2.函数参数中不能使用圆括号

// 报错
function f([(z)]) { return z; }

3.赋值语句中,不能将整个模式,或嵌

套模式中的一层,放在圆括号之中

将整个模式放在模式之中,导致报错

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];

将嵌套模式的一层,放在圆括号之中,导致报错

[({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的况

赋值语句的非模式部分,可以使用圆括号

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确

首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性
质一致

用途

1.交换变量的值

[x, y] = [y, x];

2.从函数返回多个值

// 返回一个数组
function example() {
  return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
  return {
   foo: 1,
   bar: 2
  };
}
var { foo, bar } = example();

3.函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来

function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

4.提取JSON数据

var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]

5.函数参数的默认值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};

6.便利Map结构

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}

7.输入模块的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map")

相关推荐:

ECMAScript6是什么?

ECMAScript6入门之Class对象的实例详解

ECMAScript6新增值比较函数Object.is_javascript技巧

以上がECMAScript6変数の構造化代入の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)