1. 変数を定義する
const を使用して、変更または再割り当てできない変数である定数を定義します。
- var には多くの落とし穴があるため、変数を定義するには var の代わりに let を使用します。let は、バグを修正する var と考えることができます。たとえば、var は、エラーを報告せずに変数宣言を繰り返すことができますが、var のスコープは混乱を招きます。
- ベスト プラクティス: 最初に const を使用し、変数を変更する必要がある場合は let を使用します。多くの初期のプロジェクトではまだ var が使用されていることを理解してください。
var i = 10;
console.log("var :", i);
var i = 100;
console.log("var :", i);
function test() {
var m = 10;
console.log("test m :", m);
}
test(); //console.log("test outside :", m);
let j = "hello"
console.log("j :", j);
j = "HELLO"
console.log("j :", j);
const k = [1, 2, 3, 4];
console.log("k0 :", k);
k[0] = 100;
console.log("k1 :", k);
2. 代入の破壊
ES6 では、配列とオブジェクトから値を抽出し、特定のパターンに従って変数に値を割り当てることができます。これは Destructuring と呼ばれます。
- 配列破壊代入
const arr = [1, 2, 3] //我们得到了⼀个数组
let [a, b, c] = arr //可以这样同时定义变量和赋值
console.log(a, b, c); // 1 2 3
- オブジェクトの構造化代入 (一般的に使用)
const obj = {
name: '俊哥',address:'深圳', age: '100'} //我们得到了⼀个对象
let {
name, age} = obj //可以这样定义变量并赋值
console.log(name, age); //俊哥 100
- 関数パラメータの割り当てを分解する (一般的に使用される)
const person = {
name: '⼩明', age: 11}
function printPerson({
name, age}) {
// 函数参数可以解构⼀个对象
console.log(`姓名:${
name} 年龄:${
age}`);
}
printPerson(person) // 姓名:⼩明 年龄:11
3.機能拡張
ES6 は、関数に多くの便利な拡張機能を追加します。
- パラメータのデフォルト値. ES6 以降では、関数のパラメータにデフォルト値を設定できます. go 言語にはデフォルト値がありますか?
function foo(name, address = '深圳') {
console.log(name, address);
}
foo("⼩明") // address将使⽤默认值
foo("⼩王", '上海') // address被赋值为'上海'`
- アロー関数の場合、 function を => で定義された関数に置き換えます。つまり、アロー関数は通常の関数にのみ適しており、コンストラクター、メンバー関数、またはプロトタイプ関数には適していません。
function add(x, y) {
return x + y
}//演示⾃执⾏函数
//函数也是变量,可以赋值
// 这个箭头函数等同于上⾯的add函数
(x, y) => x + y; // 如果函数体有多⾏,则需要⽤⼤括号包裹
(x, y) => {
if (x > 0) {
return x + y
} else {
return x - y
}
}
4. クラス継承
なぜならjsはもともと関数型言語として設計された、すべてが関数です。すべてのオブジェクトは関数プロトタイプから継承され、オブジェクトの継承は関数のプロトタイプを継承することによって実現されます。しかし、この書き方は新しい学者を混乱させるでしょうし、伝統的な OOP 言語とは大きく異なります。ES6 はクラス構文をカプセル化して、オブジェクトの継承を大幅に簡素化します。
class Person {
constructor(name, age) {
this.name = name
this.age = age
}// 注意:没有function关键字
sayHello() {
console.log(`⼤家好,我叫${
this.name}`);
}
}
class Man extends Person {
constructor(name, age) {
super(name, age)
}
//重写⽗类的⽅法
sayHello() {
console.log('我重写了⽗类的⽅法!');
}
}
let p = new Person("⼩明", 33) //创建对象
p.sayHello() // 调⽤对象p的⽅法,打印 ⼤家好,我叫⼩明
let m = new Man("⼩五", 33)
m.sayHello() // 我重写了⽗类的⽅法!
5. NodeJS イベント駆動型および非同期 IO を理解する
NodeJS はユーザー コード層にあり、ユーザーのコードを実行するために開始されるスレッドは 1 つだけです。==(言語に移動しますか?)==. ファイルの読み取りと書き込み、ネットワーク要求など、時間のかかる IO (ファイル IO、ネットワーク IO、データベース IO) 操作が発生するたびに、時間のかかる操作が実行のために基になるイベント ループにスローされます。待たずに、次のコードを実行し続けます。基になるイベント ループが時間のかかる IO の実行を終了すると、コールバック関数が通知として実行されます。(デモを書いてください)
同期とは、銀行に行ってビジネスの列に並び、列に並んでいる間は何もできない (ブロックされる) ことを意味し、非同期とは、銀行に行ってナンバー マシンを使用して番号を取得することを意味します。現時点では他のことを自由に行うことができます。あなたのことになると、スピーカーでイベントが通知されます。銀行システムは、時間のかかるビジネス (IO) を継続的に処理する、基礎となるイベント ループに相当します。
6. コールバック関数
- Node.js 非同期プログラミングの直接的な具現化はコールバックです
- コールバック関数は、タスクが完了した後に呼び出されます. Node は多数のコールバック関数を使用しており、Node のすべての API はコールバック関数をサポートしています.
- コールバック関数は通常、パラメーターの最後のパラメーターとして表示されます。
- ファイルの読み込み中に他のコマンドを実行できます. ファイルが読み込まれた後, ファイルの内容をコールバック関数のパラメータとして返します. このようにして、ファイル I/O 操作をブロックしたり待機したりすることなく、コードが実行されます。これにより、Node.js のパフォーマンスが大幅に向上し、多数の同時リクエストを処理できます。
function foo1(name, age, callback) {
}
function foo2(value, callback1, callback2) {
}
同期呼び出し (ブロッキング)
あらかじめカレントディレクトリに「input.txt」というファイルを用意しておき、任意のデータを書き込んでください。
var fs = require("fs");
data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程序执⾏结束!");
非同期呼び出し (ノンブロッキング)
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程序执⾏结束!");
7.モジュールシステム
Node.js ファイルが相互に呼び出せるようにするために、Node.js は単純なモジュール システムを提供します. ファイルはモジュールであり、exportキーワードを使用して実装します
//hello.js
let Hello = () => {
console.log("hello world!")
}
module.exports = Hello;
//main.js var Hello = require('./hello');
Hello();
8.パスモジュール
- path モジュールは、ファイルとディレクトリのパスを処理するためのいくつかのユーティリティ関数を提供します
- path.basename : パスの最後の部分を返します
- path.dirname : パスのディレクトリ名を返します
- path.extname : パスの拡張子を返します path.join : 指定されたパス セグメントを結合するために使用されます
- path.normalize : パスを正規化します
- path.resolve([from …], to)
var path = require("path");
// 格式化路径
console.log('normalization : ' + path.normalize('/test/test1//2slashes/1slash/tab/. .'));
// 连接路径
console.log('joint path : ' + path.join('/test', 'test1', '2slashes/1slash', 'tab', '..'));
// 转换为绝对路径
console.log('resolve : ' + path.resolve('main.js'));
// 路径中⽂件的后缀名
console.log('ext name : ' + path.extname('main.js'));
9. fs モジュール
ファイル操作に関するモジュール
- fs.stat/fs.statSync: ファイル サイズ、ファイル変更時間などのファイル メタデータへのアクセス
- fs.readFile/fs.readFileSync : ファイルを非同期/同期で読み取る
- fs.writeFile/fs.writeFileSync : ファイルを非同期/同期で書き込みます
- fs.readdir/fs.readdirSync : フォルダーの内容を読み取る
- fs.unlink/fs.unlinkSync : ファイルの削除
- fs.rmdir/fs.rmdirSync: 空でないフォルダーを削除する方法を考えて、空のフォルダーのみを削除できますか?
– fs-extra サードパーティ モジュールを使用して削除します。 - fs.watchFile : ファイルの変更を監視する
let fs = require('fs');
var filename = './testfile.txt';
//同步读取
var data = fs.readFileSync(filename);
console.log(data.toString());
//异步读取
fs.readFile(filename, function (err, data) {
console.log("========= read done!");
console.log(data.toString())
});
console.log("111111111111");
//打开⽂件
fs.open(filename, 'r+', function (err, fd) {
if (err) {
return console.err("open failed!");
}
console.log("open ok!");
})
fs.stat(filename, function (err, stat) {
console.log("is file :" + stat.isFile());
console.log("is dir :" + stat.isDirectory());
})
var output = './output.txt';
//同步写⽂件
var data = "你好"
var res = fs.writeFileSync(output, data)
console.log("res :", res); //undefine
//异步写文件
fs.writeFile(output, data, function (err) {
if (err) {
//console.log("")
}
console.log("writeFile write ok!!!")
})
fs.appendFile(output, data, function (err) {
if (err) {
//console.log("")
}
console.log("appendFile ok!!!")
})
}
10. 約束と asnyc/await
非同期およびコールバック プログラミング メソッドは CPU を最大限に活用できますが、コード ロジックがますます複雑になると、新しい問題が発生します。次のロジック コードを非同期で記述してみてください。
まず、ファイルがファイルかディレクトリかを判断し、ディレクトリの場合は、このディレクトリ内のファイルを読み取り、txt で終わるファイルを見つけて、そのファイルを取得します。サイズ。
おめでとう、上記のタスクを完了すると、究極のレベルに到達しました: コールバック地獄 コールバック地獄!
コールバック地獄の問題を解決するために、Promise と async/await が生まれました。
- promise の役割は、非同期コールバック コードをラップし、元のコールバック関数を 2 つのコールバック関数に分割することです。これには、読みやすさという利点があります。構文は次のとおりです:
構文の注意: Promise 内の resolve メソッドと reject メソッドは1 回だけ呼び出すことができ、これが呼び出されると、もう一方を呼び出すことはできません。
// 创建promise对象
let readFilePromise = new Promise(function (resolve, reject)=>{
// 在异步操作成功的情况选调⽤resolve,失败的时候调⽤reject
fs.readFile('xxx.txt', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
});
// 使⽤promise
readFilePromise.then((text) => {
//then⾥⾯就是我们传给Promise的resolve
// then⽅法是当Promise内部调⽤了resolve的时候执⾏
//then有两个参数,then(onResolve, onReject),⼀般写第⼀个即可,第⼆个通过catch来处理 //
}).catch((err) => {
//catch⽅法是当Promise内部调⽤了reject的时候执⾏
console.log(err);
})
- async/await の役割は、Promise非同期コードを同期書き込みに直接変換することですが、コードはまだ非同期であることに注意してください。このイノベーションには革命的な意義があります。
- 文法要件:
–await は async によって変更されたメソッドでのみ使用できますが、async は await を必要としません。
–await の後には、async メソッドと promise のみを指定できます。promise オブジェクトがあると仮定すると、async/await を使用して次のように記述できます。
async function asyncDemo() {
try {
// 当promise的then⽅法执⾏的时候
let text = await readFilePromise
// 当你⽤promise包装了所有的异步回调代码后,就可以⼀直await,真正意义实现了以同步 的⽅式写异步代码
console.log('异步道明执⾏');
} catch (e) {
// 捕获到promise的catch⽅法的异常
console.log(e);
}
}
asyncDemo()
console.log('我是同步代码');
小さなタスクは promise と async/await を使用して上記のロジック コードを書き換えます。強力なパワーを感じてみましょう。. 非同期コードを記述する究極の方法: 1. 最初に promise を使用して非同期コールバック コードをラップし、ノードによって提供される util.promisify メソッドを使用できます; 2. async/await を使用して非同期コードを記述します。