blog

ECMAScript2015の体系的な学習()

クロージャは、グローバル・スコープの影響を取り除くための関数スコープです。 ES2015 では、ブロックレベルのスコープを使用して、グローバル・スコープの影響を回避することができます。 forには2つ...

Dec 26, 2020 · 10 min. read

陳腐: const let var

クロージャは、グローバル・スコープの影響を回避するための関数スコープです。ES2015 では、ブロックレベルのスコープを使用して、グローバル・スコープの影響を回避することができます。

for には2つのレベルのスコープがあり、それぞれにスコープがあります。

for (let i = 0; i < 3; i++) {
 // console.log(i);
 let i = 99999
 console.log(i)
}
  
let i = 0;
if (i < 3) {
 console.log(i)
}
i ++

const と let の違い const は読み取り専用のプロパティを宣言します。const 宣言には必ず値が割り当てられます。constは、それが指すメモリ・アドレスを変更することはできません。しかし、プロパティを変更することはできます。ベストプラクティス: var は使用せず、const と let を併用します。

constとletを併用することで、宣言された変数が読み書き可能か読み取り専用かを知ることができます。あるいは読み取り専用です。これにより、予測不可能な結果を減らすことができます。

配列の分解

構造体が取り出すメンバが構造化するデータより少ない場合、左から未検索の順に分解されます。構造体によって抽出されたメンバが構造化されるデータよりも大きい場合、余剰分はundefindで返されます。

const arr = [ 100, 200, 300 ];
const [a, ...res] = arr;
console.log(a, res)
// 100 [ 200, 300 ]
// デフォルト値を割り当てる。
const [a, , , d=2 ] = arr;
console.log(d)

物体の解体

Ken に基づいて値を一致させます。

const foo = {
 'name': 'zce',
 'bar': 0x12
};
const c = 'yoom';
const {
 name: b = '123'
} = foo;
console.log(b, c);

テンプレート文字列の高度な使用法

const res = console.log ` `
出力: [ ' ' ];
const name = 'tom';
const gender = 'true'
function myTagFunc (val, name, gender) {
 console.log(val, name, gender) //   [ 'hey, ', ' is a ', '' ] 'tom' 'true'
 // 戻り値はresの値と等しい。
 return val[0] + name+ val[1] + gender + val[2]
}
const res = myTagFunc`hey, ${name} is a ${gender}`
console.log(res) // hey, tom is a true

拡張メソッド:

const bar = 'Error:\x20foo\x20is\x20not\x20defind.';
console.log(bar.startsWith(''));
console.log(bar.endsWith('。'));
console.log(bar.includes('foo'));

デフォルト値パラメータ

デフォルト値を持つパラメータは、パラメータの最後に配置する必要があります。

残りのパラメータ

es2015jsの残余引数を受け取るには、受け取る引数を使用します。

:
関数 foo () {
 console.log(arguments) // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
}
foo(1,2,3,4);
es2015: 
function foo (first, ...args) {
 console.log(first, args) // 1 [ 2, 3, 4 ] 
}
foo(1,2,3,4);

アロー関数の徹底解明

アロー関数式は、関数式よりもすっきりした構文で、独自の this、引数スーパーや新しいターゲットを持ちません。 アロー関数式は、匿名関数が必要な場合に適しています。アロー関数式は、無名関数が必要な場合に適しています。また、コンストラクタとして使用することはできません。

高度な構文です:

// 括弧付き関数本体はオブジェクト・リテラルを返す
params => ({foo: bar}) ;
// 残留パラメーターとデフォルトパラメーターをサポート。 パラメータは分解をサポートする。

独立したthisはありません。

はアロー関数の中に現れます。それぞれの新しい関数は、それがどのように呼び出されるかに基づいて、この関数のthis値を定義します。

アロー関数はそれ自身のthisを作成することはなく、スコープチェーンの1つ上のレベルのthisを継承するだけです。".現在のスコープのthisを変更する方法は一切ありません。".

whileは、私が終了するまでメインプロセスの実行をブロックします。

オブジェクトリテラルの強化

const bar = '345';
const obj = {
 foo: 123,
 // 同じ名前で定義された変数は、次のように省略できる。
 bar,
 // 同じ名前の関数や匿名関数の場合は省略できる。
 method1() {
 console.log(this, 888)
 }
 // プロパティ名が変数の場合は、角括弧で囲んで書くことができる。
 [Math.random()]: 123;
}
console.log(obj);
obj.method1()

Object.assignは

Object.assignはディープコピーですか? そうではありません。単なる列挙可能なプロパティの値のコピーです。オブジェクトへの参照であればオブジェクトへの参照であれば、参照の値をコピーするだけです。

const foo = {
 'a': 0x7b,
 'b': 0x7b
};
const bar = {
 'a': 0x315,
 'd': 0x315
};
const B = {
 'a': 0x1c8,
 'c': 0x1c8
};
const A = Object.assign(B, foo, bar);
console.log(B === A, B);
function Obj(C) {
 let Foo = Object.assign({}, C);
 Foo.name = 'func\x20obj';
 console.log(Foo, 0x2);
}
const Bar = { 'name': 'global\x20obj' };
Obj(Bar);
console.log(Bar);

Object.isは、2つの値が等しいかどうかを判定します。

console.log(Object.is(NaN, NaN), Object.is(-0x0, +0x0));

Object.defineProperty 和 Proxy

Object.definePropertyはオブジェクトの削除をリッスンしません。
const obj = {
 'name': 'zce',
 'b': 0x14
};
const a = new Proxy(obj, {
 'deleteProperty'(c, bar) {
 console.log('delete', bar);
 delete c[bar];
 }
});
delete a.b;
console.log(a, obj, a === obj);

Proxyはオブジェクトのアクセスプロキシとして特別に設計されています。オブジェクトは読み書きできます。

const person = {
 name: 'zce',
 age: 20
};
// Proxy 最初のパラメーターはプロキシされるオブジェクトである。 2番目のパラメータはオブジェクトである。このオブジェクトはget set deletePropertyメソッドを持つ。
const personProxy = new Proxy(person, {
// getこのメソッドには2つのパラメータがある。ひとつはプロキシのオブジェクト。ひとつは渡されたプロパティ。
// このプロパティはあってもなくてもよい。
 取得する {
 // 属性が存在する場合、その属性を返す。 存在しない場合はデフォルト値を返す。 
 return property in target ? target[property] : '私は君が望むものを持っていない。';
 },
 // setメソッドを使用する。引数は3つある。 target プロキシのオブジェクト。 property: 渡されたプロパティ。このプロパティはあってもなくてもよい。ない場合は新しいプロパティとなる。
 もしあれば、それは古いプロパティの更新である。 内部では、好きなように論理的な判断ができる。
 セット{
 if (property === 'age' && !Number.isInteger(value)) {
 throw new TypeError(`${value} is not an int`)
 }
 target[property] = value
 }
})
personProxy.age = true;
console.log(personProxy.name);
console.log(personProxy.a);
console.log(personProxy);

VUE では、配列のメソッドはオーバーライドされます。配列のプロトタイプのメソッドを置き換えます。リスニングの目的を達成するためです。また、Proxy は配列の変更をリッスンするのに非常に適しています。

プロキシは配列をリッスンします。

const list = [];
// 第1引数は配列である。
セット経由でブッシュからのデータをリッスンする。
const listProxy = new Proxy(list, {
 set (target, property, value) {
 console.log('set', property, value,0);
 target[property] = value;
 return true;
 }
})
listProxy.push(100)
listProxy.push(10)
set 0 100 0 // 出力 なぜか両サイドに出力される。
set length 1 0
set 1 10 0
set length 2 0

class

関数のインスタンス・オブジェクトを作成するのは、es6ではよくあることでした。関数を書いて、その関数の中にthis.インスタンスのプロパティ。プロトタイプにインスタンスを生成するメソッド。es6ではclassキーワードでインスタンスを生成します。コンストラクタの中に属性を書きます。class LKWineList extends Component : extendsはこのキーワードで継承できます。

class Person {
 constructor(name) {
 this.name = name
 } 
 say () {
 console.log(`hi, my name is ${this.name}`)
 }
}
const p = new Person('tom');
p.name 

static

es2015では、クラスのstaticメソッドを作成することができます。これらのメソッドには、クラス名を使用して直接アクセスできます。しかし、このような静的メソッドはインスタンスではなくクラスを指します。

class foo {
 static .c(obj) {
 return new foo(obj);
 }
 constructor(b) {
 console.log(b);
 }
 .bar() {
 console.log(0x7b);
 }
}
const a = foo.c('333');
a.bar();

extends

キーワードを使用して継承します。

// extends 継承のキーワード
class Student extends Person {
 constructor(number){
 super() // 親クラスのメソッドを継承するかどうか。
 this.number = number;
 }
 hello () {
 super.created(); // 親セット・クラスのメソッドを呼び出す。
 console.log(this.number)
 }
}
const s = new Student('jack', 100);
s.hello()

set

アクションの配列の強調を解除します。

const s = new Set();
s.add : addメソッドは要素を追加する。その要素が、その後に追加される要素の中にすでにある場合は無視される。
s.size: new Set() の長さを取得する。
s.has: new Set() に値があるかどうかを判定する。真を返す false.
s.delete: 要素を削除し、残りの要素を返す。
s.clear() クリアセット.
for of またはforEachトラバーサルである。
const arr = [1,2,3,33,2,1];
const result = new Array(new Set(arr));
const res = [...new Set(arr)]
console.log(res, result)

マップはオブジェクトに似ています。

MapとObjectの違いは、Mapはロバストとして任意の型を指定できることです。オブジェクトはtostring()の結果をロバストとして使用します。その結果、名前が重複します。あるいは使用できません。

const obj = {}
obj[true] = 'value';
obj = 'value';
obj[{a: 1}] = 'value';
// console.log(Reflect.ownKeys(obj))
// console.log(obj['[object Object]'])
const m = new Map();
const tom = {name: 'tom'}
m.set(tom, 90)
console.log(m)
console.log(m.get(tom))
m.forEach((val, key) => {
 console.log(val, key)
})

Symbol 新しいプリミティブデータ型。

Symbol()は重複せずに作成されます。その主な機能は、オブジェクトに固有のプロパティ名を追加することです。

// shared.js =============
 const cache = {}
// a.js ==================
cache['foo'] = Math.random()
// b.js ==================
cache['foo'] = '123'
console.log(cache);
const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
s1 === s2 // forメソッドは、2つの文字列が等しいことを示すことができる。
console.log(Symbol.for(true) === Symbol.for('true') // はSymbolを生成する前に文字列に変換される。.
const obj = {}
console.loh(obj.toString() // '[object Onject]' // toString 
// カスタムラベルも可能だ。
const obj = {
 [Symbol.toStringTag]: XObject
}
console.log(obj.toString) // [object XObject]
for in このプロパティでは利用できない。
Object.getOwnPropertySymbols(obj) // Symbolで設定したプロパティの名前を取得できる。
つまり、Symbolはオブジェクトのプライベート・プロパティを設定するのに適しているのだ。

for of

for in は、値のペアを走査します。

for of はそれらすべてを走査します。

const bar = new Map();
bar.set('foo', '123');
bar.set('bar', '345');
for (let [a, b] of bar) {
 console.foo(a, b);
}

オブジェクトを反復処理するためにfor ofを使うと、エラーが発生します。これは、走査できるすべてのオブジェクトにイテレータ・メソッドがあるからです。イテレータの実装

const obj = {
 store: ['foo', 'bar', baz]
 [Symbol.inerator]: function () {
 let index = 0;
 const self = this
 
 return {
 next: function () {
 const result = {
 value: self.store[index],
 done: index >= self.store.length
 }
 index ++
 return ++
 }
 }
 }
}
for (const item of obj) {
 console.log(item)
}

イテレータを実装する意味それは、統一された走査インターフェースを外部に提供することです。そうすることで、外部はデータの内部構造がどうなっているかを気にする必要がなくなります。

const todos = {
 life: [' ', ' ', ' '],
 learn: [' ', ' ', ' '],
 work: [' '],
 // トラバーサル・データを提供する
 each: function () {
 const all = [].concat(this.life, this.learn, this.work);
 for (const e of all) {
 console.log(e)
 }
 },
 // 統一されたトラバーサル・メソッド・イテレータを提供する。
 [Symbol.iterator]: function() {
 const all = [...this.life, ...this.learn, ...this.work];
 let index = 0;
 return {
 next: function () {
 return {
 value: all[index],
 done: index++ >= all.length
 }
 }
 }
 }
}
for (const e of todos) {
 console.log(e)
}
console.log('---------------')
todos.each()

ジェネレータ関数

ジェネレータは内部的にイテレータ

function* a() {
 console.log('1111');
 yield 0x64;
 console.log('2222');
 yield 0xc8;
 console.log('3333');
 yield 0x12c;
}
const bar = a();
console.log(bar.next());
console.log(bar.next());
console.log(bar.next());
console.log(bar.next());

アプリケーションを実装しています。

const todos = {
 life: [' ', ' ', ' '],
 learn: [' ', ' ', ' '],
 work: [' '],
 // トラバーサル・データを提供する
 each: function () {
 const all = [].concat(this.life, this.learn, this.work);
 for (const e of all) {
 console.log(e)
 }
 },
 // 統一されたトラバーサル・メソッド・イテレータを提供する。
 [Symbol.iterator]: function * () {
 const all = [...this.life, ...this.learn, ...this.work];
 for (const e of all) {
 yield e
 }
 
 }
}
for (const e of todos) {
 console.log(e)
}

ECMAScript 1026

は配列がこの値を持つかどうかを判定します。ブール値を返します。

const obj = [
 'foo',
 0x1,
 NaN,
 false
];
console.log(obj.indexOf('foo'));
console.log(obj.indexOf(0x1));
console.log(obj.indexOf(NaN));
console.log(obj.includes(NaN));
console.log(obj.indexOf(false));

指数演算子

console.log(Math.pow(2, 10); // 2の10乗
console.log(2 ** 10) // 2の10乗 ECMAScript 2016

ECMAScript 1027

オブジェクトの拡張メソッド Object.values() // オブジェクトの値を取得します。オブジェクトの値を取得します。

const obj = {
 foo: 'values',
 bar: 'values'
};
console.log(Object.entries(obj))
console.log(new Map(Object.entries(obj)));
const map = new Map(Object.entries(obj));
for (const e of map) {
 console.log(e[0])
 console.log(e[1])
}
//  
[ [ 'foo', 'values' ], [ 'bar', 'values' ] ]
Map { 'foo' => 'values', 'bar' => 'values' }
foo
values
bar
values

Object.getOwnPropertyDescriptors(p);

内部プロパティをディープ・コピーします。

const p = {
 firstName: 'lei',
 lastName: 'wang',
 get fullName () {
 return this.firstName + this.lastName
 }
}
const cp = Object.assign({}, p)
console.log(p) // { firstName: 'lei', lastName: 'wang', fullName: [Getter] }
console.log(cp) // { firstName: 'lei', lastName: 'wang', fullName: 'leiwang' } // フルネームの実行結果をコピー
const des = Object.getOwnPropertyDescriptors(p); // 読み書き可能なオブジェクトのすべてのプロパティを取得する
const p2 = Object.defineProperties({}, des);
console.log(p2) // { firstName: 'lei', lastName: 'wang', fullName: [Getter] } すべてコピーした。
p2.firstName = '333';
console.log(p2.fullName) // 333wang 修正は互いに影響しない
console.log(p.fullName) // leiwang
Read next

暗号通貨の世界でイーサはどこへ行くのか?

このアルゴリズムはHashimotoのアイデアの多くを借用しています。HashimotoはThaddeusDryjaによって提案されました。

Dec 25, 2020 · 2 min read