Ecmascript 6
- ECMAScript 6.0(以下簡稱ES6)是JavaScript語言的下一代標(biāo)準(zhǔn),已經(jīng)在2015年6月正式發(fā)布了。
- Ecmascript 是 JavaScript 語言的標(biāo)注規(guī)范
- JavaScript 是 Ecmascript 規(guī)范的具體實(shí)現(xiàn)
- 具體實(shí)現(xiàn)取決于各大瀏覽器廠商的支持進(jìn)度
- Ecmascript 6 也被稱作 Ecmascript 2015
- 各大瀏覽器廠商對于最新的 Ecmascript 6 標(biāo)準(zhǔn)支持可以參照:
- 對于不支持 ES6 的環(huán)境,可以使用一些編譯轉(zhuǎn)碼工具做轉(zhuǎn)換處理再使用
- 例如 babel
let 和 const
let:
- let 類似于 var,用來聲明變量
- 通過 let 聲明的變量不同于 var,只在 let 命令所在的代碼塊內(nèi)有效(塊級作用域)
- let 聲明的變量不存在變量提升
- let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量
const:
- const聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變
- const 聲明必須初始化
- const的作用域與let命令相同:只在聲明所在的塊級作用域內(nèi)有效
- const命令聲明的常量也是不提升,必須先聲明后使用
- const聲明的常量,也與let一樣不可重復(fù)聲明
解構(gòu)賦值
ES6 允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)。
數(shù)組解構(gòu):
let [a, b, c] = [123, 456, 789]
console.log(a, b, c) 123 456 789
對象解構(gòu):
let { name, age } = { name: 'Jack', age: 18 }
console.log(name, age) Jack 18
函數(shù)參數(shù)解構(gòu):
function f (p1, { p2 = 'aa', p3 = 'bb' }) {
console.log(p1, p2, p3)
}
f('p1', { p2: 'p2' }) p1 p2 bb
字符串解構(gòu):
let [a, b, c, d, e] = 'hello'
console.log(a, b, c, d, e) h e l l o
字符串
實(shí)用方法:
includes(String):返回布爾值,表示是否找到了參數(shù)字符串。
startsWith(String):返回布爾值,表示參數(shù)字符串是否在源字符串的頭部。
endsWith(String):返回布爾值,表示參數(shù)字符串是否在源字符串的尾部。
repeat(Number):repeat方法需要指定一個(gè)數(shù)值,然后返回一個(gè)新字符串,表示將原字符串重復(fù)Number次。
模板字符串:
let basket = { count: 5, onSale: true }
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
- 模板字符串(template string)是增強(qiáng)版的字符串,用反引號(`)標(biāo)識
- 它可以當(dāng)作普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量
- 如果使用模板字符串表示多行字符串,所有的空格和縮進(jìn)都會(huì)被保留在輸出之中
- 模板字符串中嵌入變量,需要將變量名寫在
${}
之中- 大括號內(nèi)部可以放入任意的JavaScript表達(dá)式,可以進(jìn)行運(yùn)算,以及引用對象屬性
- 大括號內(nèi)部還可以調(diào)用函數(shù)
數(shù)組
方法:
Array.from() 將一個(gè)偽數(shù)組轉(zhuǎn)為一個(gè)真正的數(shù)組
實(shí)際應(yīng)用中,常見的類似數(shù)組的對象是DOM操作返回的NodeList集合,
以及函數(shù)內(nèi)部的arguments對象。Array.from都可以將它們轉(zhuǎn)為真正的數(shù)組。
Array.of() Array.of方法用于將一組值,轉(zhuǎn)換為數(shù)組
這個(gè)方法的主要目的,是彌補(bǔ)數(shù)組構(gòu)造函數(shù)Array()的不足。
因?yàn)閰?shù)個(gè)數(shù)的不同,會(huì)導(dǎo)致Array()的行為有差異。
find() 查找數(shù)組中某個(gè)元素
findIndex() 查找數(shù)組中某個(gè)元素的索引下標(biāo)
includes() 返回一個(gè)布爾值,表示某個(gè)數(shù)組是否包含給定的值,與字符串的includes方法類似
實(shí)例方法:
ES6提供三個(gè)新的方法——entries(),keys()和values()——用于遍歷數(shù)組.
可以用 for...of
循環(huán)進(jìn)行遍歷,唯一的區(qū)別是 keys()
是對鍵名的遍歷、
values()
是對鍵值的遍歷,entries()
是對鍵值對的遍歷。
entries()
keys()
values()
函數(shù)的擴(kuò)展
函數(shù)參數(shù)的默認(rèn)值:
ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面。
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') Hello World
log('Hello', 'China') Hello China
log('Hello', '') Hello
- 通常情況下,定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)
- 因?yàn)檫@樣比較容易看出來,到底省略了哪些參數(shù)
- 如果非尾部的參數(shù)設(shè)置默認(rèn)值,實(shí)際上這個(gè)參數(shù)是沒法省略的。
- 指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個(gè)數(shù)
- 也就是說,指定了默認(rèn)值后,length屬性將失真
rest 參數(shù):
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) 10
擴(kuò)展運(yùn)算符:
console.log(...[1, 2, 3]) 1 2 3
console.log(1, ...[2, 3, 4], 5) 1 2 3 4 5
箭頭函數(shù):
var f = v => v
上面的箭頭函數(shù)等同于:
var f = function(v) {
return v
}
- 箭頭函數(shù)體內(nèi)的this指向,跟隨它定義(聲明)時(shí)所在的上下文this。比如它被定義在某個(gè)函數(shù)內(nèi),就跟隨這個(gè)函數(shù)的this。
- 箭頭函數(shù)不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤
- 箭頭函數(shù)內(nèi)部不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在
- 如果要用,可以用Rest參數(shù)代替
對象
屬性的簡潔表示法:
var foo = 'bar';
var baz = {foo};
baz {foo: "bar"}
等同于
var baz = {foo: foo}
除了屬性簡寫,方法也可以簡寫:
var o = {
method() {
return "Hello!"
}
}
等同于
var o = {
method: function() {
return "Hello!"
}
}
babel
詳細(xì)配置使用方式請見:http://es6.ruanyifeng.com/#docs/intro#Babel轉(zhuǎn)碼器
在線教育項(xiàng)目
npm scripts
目標(biāo)
- 能掌握 let 和 const 的用法并解釋它們的作用
- 能掌握解構(gòu)賦值的基本使用(數(shù)組、對象、函數(shù)參數(shù))
- 能掌握模板字符串的基本使用
- 能掌握數(shù)組中擴(kuò)展的新方法(Array.from()、Array.of()、find、findIndex、includes)
- 能掌握ES6中函數(shù)的一些特性使用方法(參數(shù)默認(rèn)值、rest參數(shù)、擴(kuò)展運(yùn)算符、箭頭函數(shù))
- 能掌握ES6中模塊化的基本用法(import、export、export default)
- 能掌握 babel 的基本使用(配置完成對在線教育項(xiàng)目中由開發(fā)環(huán)境代碼到生產(chǎn)環(huán)境代碼的轉(zhuǎn)換)
- Ecmascript 6 + Babel
- npm scripts
- Express
Babel Register
第一:在項(xiàng)目根目錄下創(chuàng)建一個(gè) .babelrc
文件,寫入以下內(nèi)容:
{
"presets": [
]
}
第二:安裝對應(yīng)的轉(zhuǎn)碼規(guī)則:
$ npm install --save-dev @babel/preset-env
# react轉(zhuǎn)碼規(guī)則
$ npm install --save-dev @babel/preset-react
第三:將 .babelrc
文件中修改為以下內(nèi)容:
{
"presets": [
"@babel/env",
"@babel/preset-react"
],
"plugins": []
}
第四步(從第四步開始,前三部必不可少):
- @babel/cli:命令行轉(zhuǎn)碼
- @babel/node:babel-node命令,提供一個(gè)支持ES6的REPL環(huán)境
- @babel/register:實(shí)時(shí)轉(zhuǎn)碼,所以只適合在開發(fā)環(huán)境使用
- @babel/core:babel7.0以后,默認(rèn)都需要安裝@babel/core模塊,作用是調(diào)用Babel的API進(jìn)行轉(zhuǎn)碼
@babel/cli:
npm install --save-dev @babel/cli
這種第三方命令行工具如果安裝到本地項(xiàng)目,會(huì)在 node_modules
中生成一個(gè)目錄:.bin
,
然后第三方命令行工具會(huì)將對應(yīng)的可執(zhí)行文件放到該目錄中。
這樣的話,就可以直接在本地項(xiàng)目中使用該第三方命令行工具了。
對于如何使用,則可以通過配置 package.json
文件中的 scripts
字段來配置使用:
{
"name": "babel-demo",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx babel demo1.js"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"@babel/register": "^7.9.0"
"@babel/preset-react": "^6.22.0"
}
}
babel-register(適合開發(fā)階段,實(shí)時(shí)編碼轉(zhuǎn)換):
第一:安裝 babel-register
npm install --save-dev @babel/register;
第二:添加一個(gè)傀儡文件(main.js):
require('@babel/register');
require('你的核心功能代碼入口文件模塊')
第三:使用 node 執(zhí)行 main.js
,而不是你的入口文件.
--save 和 --save-dev
通過 --save
參數(shù)安裝的包,是將依賴項(xiàng)保存到 package.json 文件中的 dependencies 選項(xiàng)中。
通過 --save-dev
參數(shù)安裝的包,是將依賴項(xiàng)保存到 package.json 文件中的 devDependencies 選項(xiàng)中。
無論是 --save
或者 --save-dev
安裝的包,通過執(zhí)行 npm install
都會(huì)將對應(yīng)的依賴包安裝進(jìn)來。
但是,在開發(fā)階段會(huì)有一些僅僅用來輔助開發(fā)的一些第三方包或是工具,然后最終上線運(yùn)行(到了生產(chǎn)環(huán)境),
這些開發(fā)依賴項(xiàng)就不再需要了,就可以通過 npm install --production
命令僅僅安裝 dependencies
中的
依賴項(xiàng)。
Express
基本路由
根據(jù)不同的請求路徑分發(fā)到具體的請求處理函數(shù)
模板引擎配置
// config.js
import {
join
} from 'path'
export default {
viewPath: join(__dirname, '../views'),
node_modules_path: join(__dirname, '../node_modules'),
public_path: join(__dirname, '../public')
}
app.js
app.set('views', config.viewPath)
app.set('view engine', 'ejs')
模版引擎一般不用ejs,功能太單一,這里只是舉例
中間件
用來處理 http 請求的一個(gè)具體的環(huán)節(jié)(可能要執(zhí)行某個(gè)具體的處理函數(shù))
中間件一般都是通過修改 req 或者 res 對象來為后續(xù)的處理提供便利的使用
中間件分類:
use(function () {req, res, next})
不關(guān)心請求方法和請求路徑,沒有具體路由規(guī)則,任何請求都會(huì)進(jìn)入該中間件
use('請求路徑', function (req, res, next) {})
不關(guān)心請求方法,只關(guān)心請求路徑的中間件
get('請求路徑', function (req, res, next) {})
具體路由規(guī)則中間件
post('請求路徑', function (req, res, next) {})
中間件的作用
1. 處理靜態(tài)資源
app.use('/public', express.static('開放目錄的路徑'))
在 use 方法中,如果指定了第一個(gè)路徑參數(shù),則通過 req.path 獲取到的是不包含該請求路徑的字符串,例如當(dāng)前路徑參數(shù)是/public
,請求路徑是 /public/a.jpg
則通過 req.path 拿到的就是 a.jpg
;請求路徑是/public/a/a.css
,得到的req.path則是a/a.css
目前已知傳遞給了 static 方法一個(gè)絕對路徑 c:/project/public
,假設(shè)目前請求是 /public/a/a.css
拿到的 req.path 是a/a.css
,實(shí)際資源通過c:/project/public/
+ a/a.css
拼接起來讀取
自己封裝static方法,模擬express內(nèi)置中間件(static)
const fs = require('fs')
const path = require('path')
const app = express()
function static(dirPath) {
return (req, res, next) => {
const filePath = path.join(dirPath, req.path)
fs.readFile(filePath, (err, data) => {
if (err) {
return res.end("404 Not Found")
}
res.end(data)
})
}
}
app.use('/public', static(path.join(__dirname, 'public')))
app.use('/node_modules', static(path.join(__dirname, 'node_modules')))
2. 處理錯(cuò)誤(記錄和和給用戶友好體驗(yàn))
const express = require('express')
const fs = require('fs')
const app = express()
app.get('/', function aaa(req, res, next) {
// 通過 JSON.parse 解析查詢字符串中的某個(gè)
try {
const data = JSON.parse('{abc')
res.json(data)
} catch (e) {
next(e)
}
})
帶參數(shù)的next(err)只能被具有四個(gè)參數(shù)的處理中間件匹配到,即如下中間件。
這個(gè)中間件就是用來全局統(tǒng)一處理錯(cuò)誤的,一般都放在最后,如果放在前面后面的中間件發(fā)生錯(cuò)誤時(shí)再傳next(e)就匹配不到了。和處理404同理。
// 該中間件只有被帶有參數(shù)的 next 才能調(diào)用到
// 注意:這里一定要寫全四個(gè)參數(shù),否則會(huì)導(dǎo)致問題
app.use((err, req, res, next) => {
const error_log = `
====================================
錯(cuò)誤名:${err.name}
錯(cuò)誤消息:${err.message}
錯(cuò)誤堆棧:${err.stack}
錯(cuò)誤時(shí)間:${new Date()}
====================================\n\n\n`
fs.appendFile('./err_log.txt', error_log, err => {
res.writeHead(500, {})
res.end('500 服務(wù)器正忙,請稍后重試')
})
})
// 404 處理中間件
app.use((req, res, next) => {
res.end('404')
})
Express API
- express()
- Application
- Request
- Response
- Router
知識點(diǎn)
- Nunjucks 模板引擎
- Mongoose ORM 對象模型映射
在線教育項(xiàng)目
使用 Nunjucks 模板引擎抽取模板頁
廣告管理
路由設(shè)計(jì)
請求方法 | 請求路徑 | 查詢字符串 | 請求體 | 路徑參數(shù) | 作用 |
---|---|---|---|---|---|
GET | /advert | 渲染廣告管理列表頁 | |||
GET | /advert/add | 渲染添加廣告頁面 | |||
POST | /advert/add | image、link、start_time、end_time、title、create_time、last_modified | 處理添加廣告請求 | ||
nvm
Node Version Management
-
nvm list
查看所有已安裝的 node 版本 -
nvm install
版本號 安裝指定版本的 node -
nvm use
版本號 切換到指定版本號 -
nvm proxy
代理地址 配置代理進(jìn)行下載
nrm(Node registry manager)
作用:npm下載鏡像配置管理
使用淘寶的 cnpm 鏡像源下載:
npm install --save express --registry=https://registry.npm.taobao.org
第一:
npm install -g nrm
基本使用:
nrm list
打印可選擇的鏡像地址列表,當(dāng)前的鏡像前面有標(biāo)注*
nrm use taobao
選擇列表中的一個(gè)鏡像別名進(jìn)行配置
Yarn
Yarn 是一個(gè) Facebook 開源的一個(gè)類似于 npm 的一個(gè)包管理工具,也就是 npm 能做的,yarn 也能做。
安裝:
npm install -g yarn
使用:
# npm init
yarn init
# npm install --save/-S 包名
yarn add 包名
# npm install --save-dev/-D,安裝開發(fā)依賴 devDependencies
yarn add --dev/-D 包名
# 離線安裝
yarn add 包名@版本號 --offline
# npm install
yarn install
# npm uninstall 包名
yarn remove 包名
# npm install -g 包名
yarn global add 包名
# npm uninstall -g 包名
yarn global remove 包名
目標(biāo)
- 能掌握理解 Express 中間件執(zhí)行機(jī)制并舉例
- 能掌握利用 Express 中間件處理網(wǎng)站 404
- 能掌握 Express 中間件統(tǒng)一處理全局錯(cuò)誤
- 能掌握 Nunjucks 模板引擎的基本使用(布局功能)
- 能掌握利用 Express 中間件解析表單 POST 請求體