第二章

50591 ワード

2章で知るJavaScript


2.1 ES2015


JavaScriptは毎年新しいバージョンに更新されています.ノードも定期的にバージョンをアップグレードし、変更されたJavaScript構文を反映します.この本はES 2015の文法を述べている.

2.1.1 const, let


Cと異なり、変数タイプを別途指定する必要はありません.以前はvarタイプが使用されていたが、ES 2015以降はconstとlet変数が使用され、constとletはvar(関数スキャン)とは異なりblockscopeであるため、ブロック外では変数にアクセスできない.
constは定数宣言であり、通常、初期化変数に他の値を割り当てることは少ないため、デフォルトではconstを使用して他の値を割り当てる必要がある場合にletが使用されます.

2.1.2テンプレート文字列


ES 2015に新しく登場した文字列.従来のアプローチは次のとおりです.
let num1 = 1;
let num2 = 2;
let result = 3;
let string1 = num1 + ' 더하기 ' + num2 + ' 는 \' ' + result + ' \'';
console.log(string1);
上のように、可読性が低下します.
新しい形態は下図のようにずっときれいになった.
let num1 = 1;
let num2 = 2;
let result = 3;
let string1 = `${num1} 더하기 ${num2}는 '${result}'`;
console.log(string1);

2.1.3対象分離

 let sayNode = function(){
 	console.log('node');
 }
 let es = 'ES';
 let oldObjec = 
 {
 	sayJS: function(){
 		console.log('JS');
 	},
 	sayNode: sayNode,
 };
 oldObject[es + 6] = 'Fantastic';
 oldObject.sayNode(); 
 oldObject.sayJS();
 console.log(oldObject.ES6;
上のコードは以下のように書くことができます.
 const newObject = {
 	sayJs() {
 		console.log('JS');
 	},
 	sayNode, 
 	[es + 6] : 'Fantastic',
 };
 newObject.sayNode();
 newObject'sayJS();
 console.log(newObject.ES6);
(:)と関数を追加する必要はありません.sayNode:属性名と変数名が同じ場合は、一度だけ書き込みます.

2.1.4矢印関数

function add1(x, y){
	return x + y;
}
const add2 = (x, y){
	return x + y;
}
const add3 = (x, y) => x + y;
const add4 = (x, y) => (x + y);
function not(x){
	return !x;
}
const not2 = x => !x;
関数宣言ではなく=>記号として宣言できます.変数に置き換えると、後で再使用できます.矢印関数にreturn文がある限り、returnではなくreturn式を直接書くことができます.きれいにするために、括弧で囲みます.
var relationship1 = {
	name: 'zero'
	friends: ['nero', 'hero', 'xero'],
	logFriends: fucntion() {
		var that = this;
		this.friends.forEach(friend) {
			console.log(that.name, freind);
		});
	},
};
relationships1.logFreinds();
const relationship2 = {
	name: 'zero',
	friends: ['nero', 'hero', 'xero'],
	logFriends() {'
		this.friends,firEach(friend => {
			console.lgo(this.name, freind);
	 	});
	},
};
relationship2.logFriends();
上記の式は異なる関数スキャンのthisを持つため、forEachはthis変数を使用して関係1に間接的にアクセスします.以下に示す矢印関数を使用して、外部スキャンのlogFreinds()のthisを使用できます.上尉スコフのこの点を受け継ぐ.すなわち、デフォルトでは矢印関数が使用され、この関数を使用する必要がある場合は、矢印関数と関数宣言(function)の間で選択するだけです.

2.1.5構造分解配分


構造分解割り当てにより、オブジェクトと配列から属性または要素を簡単に抽出できます.
var candyMachine = {
	status: {
		name: 'node',
		count: 5,
	},
	getCandy: function (){
		this.status.count--;
		return this.status.count;
	},
};
var getCandy = cndyMachine.getCandy;
var count = candymachine.status.count;
const candyMachine = {
	status: {
		name: 'node',
		count: 5,
	},
	getCandy() {
		this.status.count--;
		retun this.status.count;
	},
};
const { getCandy, status: {count} } = candyMatione;
candyMachineオブジェクトでプロパティを検索し、変数と一致させます.countのように複数のステップでプロパティを検索することもできます.getCandyとcount変数が初期化されました.しかし,構造分解割当ては関数のthisを変える可能性がある.thisを変更する場合は、bind関数をdaとして使用する必要があります.アレイの構造分解割り当て構文も存在します.
var array = ['node', {}, 10, true];
var node = array[0];
var obj = array[1];
var bool = array[3];
const array = ['node', {}, 10, true];
const [node, obj, ,bool] = array;

2.1.6クラス


クラス構文が追加されました.しかし、他の言語のようにクラスに基づいているのではなく、プロトタイプに基づいています.君はただきれいにするためにクラスを変えただけだと理解している.
var Human = function(type) {
	this.type = type || 'human';
};
Human.isHuma = function(human) {
	return human instanceof Human;
}
Human.prototype.breathe = function() {
	alert('hammm');
};
var Zero = function(type, fistName, lastName) {
	Human.apply(this, arguments);
	this.firstName = firstName;
	this.lastName = lastName;
};
Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero;
Zero.prototype.sayName = fuction() {
	alert(this.firstName + ' ' this.lastName);
};
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero);
Human.applyとObject.create部分は継承された部分です.
class Huamn {
	constructor(type = 'human') {
		this.type = type;
	}
	static isHuman(human) { 
		return human instanceof Human;
	}
	breathe() {
		alert('hammm');
	}
}
class Zero extends Human {
	constructor(type, firstName, lastName) {
		super(type);
		this.firstName = firstName;
		this.lastName = lastName;
	}
	 sayName(){
		super.breathe();
		alter~~~;
	}
}
const newZero = new Zero('human', 'Zero', 'Cho');
 Human.isHuman(newZero);
クラス全体のグループが表示されます.コンストラクション関数関数関数はコンストラクション関数に入ります.Human.クラス関数(ishumanなど)は静的キーに切り替えられます.プロトタイプ関数もクラスブロックに含まれ、どの関数がどのクラスに属するかを表示します.継承も簡単になり、extendsキーワードに簡単に継承できます.ただし、class構文に変更してもjavascriptはプロトタイプベースであることを覚えておいてください.

2.1.7プロミズ


JavaScriptはノード上で主に非同期アクセスである.特にイベントリスナーを使用する場合、コールバック関数がよく使用されます.しかしES 2015からJava ScreetとNodeのapiはコールバックではなくプロセスベースと評価され、コールバック地獄現象を克服した.
const condition = true; 
const promise = new promise((resolve, reject) => {
	if(condition) {
		resolve('성공');
	}else {
		reject('실패');
	}
});
//다른코드
promise
	.then((message) => {
		console.log(message);
	})
	.catch((error) => {
		console.error(error);
	})
	.finally(() => {
		console.log('무조건');
	});
new promiseを使用してプロセスを作成し、resolveとrejectをパラメータとするコールバック関数を内部に追加できます.このように生成されたpromise変数にthenメソッドとcatchメソッドを追加できます.resolveが呼び出されると、executeが呼び出されるとcatchが実行されます.finallyはthenとcatchのパラメータから無条件実行解析と拒否に組み込まれたパラメータを得ることができる.promisを簡単に説明すると、実行はオブジェクトですが、結リンゴ値は後で受信するオブジェクトです.thenまたはcatchでは、別のthenまたはcatchを再度追加できます.前のreturn値をthenのパラメータに返します.ただし、次のthenで受信できるのはthenでnewPromiseを返すことだけです.複数のプロセスを一度に実行する方法はPromiseです.allを利用するのは簡単です.
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
	.then((result) => {
		console.log(result);
	})
	.catch((error) => {
		console.error(error);
	};
Promise.allは1つだけ失敗してもcatchに移動します.失敗したものだけを選ぶこともできます.

2.1.8 async/await


より簡潔な文法
function findAndSaveUser(Users) {
	Users.findOne({})
		.then((user) => {
			user.name = 'zero';		
			return user.save();
		})
		.then((user) => {
			return Users.findOne({ gender: 'm'});
		})
		.catch(err => {
			console.error(err);
		});
	}
以上のコードはasync/await構文を用いて以下に示す.
async function findAndSaveUser(Users) {
	let user = await Users.findOne({});
	user.name = 'zero';
	user = await user.save();
	user = await Users.findOne({ gender: 'm' });
}
これで、関数は解析を待ってスキップされます.エラー部分を追加する手順は、次のとおりです.
async function findAndSaveUser(Users) {
	try {
		let user = await Users.findOne({});
	 	user.name = 'zero';
		user = await user.save();
	 	user = await Users.findOne({ gender: 'm' });
	} catch (error) {
		console.error(error);
	}
}
화살표 함수도 같이 사용 가능
  const findAndSaveUser = async (Users) => {
	try {
		let user = await Users.findOne({});
	 	user.name = 'zero';
		user = await user.save();
	 	user = await Users.findOne({ gender: 'm' });
	} catch (error) {
		console.error(error);
	}
}
for文に示すようにpromisは順次実行できます.(ES2018+)
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
	for await (promise of [promise1, promise2]) {
		console.log(promise);
	}
})();
async関数の戻り値は常にPromiseによって包まれます.したがって,実行後にthenを加えるか,別のasync関数にwaitを加えて処理することができる.
async function findAndSaveUser(Users) {
//
}
findAndSaveUser().then(() => {..});
async function other() {
	const result - await findAndSaveUSer();
}