前端學(xué)習(xí)筆記四十五-ES6、babel配置、在線教育項(xiàng)目

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

請參考:阮一峰 - npm scripts 使用指南


目標(biāo)

  1. 能掌握 let 和 const 的用法并解釋它們的作用
  2. 能掌握解構(gòu)賦值的基本使用(數(shù)組、對象、函數(shù)參數(shù))
  3. 能掌握模板字符串的基本使用
  4. 能掌握數(shù)組中擴(kuò)展的新方法(Array.from()、Array.of()、find、findIndex、includes)
  5. 能掌握ES6中函數(shù)的一些特性使用方法(參數(shù)默認(rèn)值、rest參數(shù)、擴(kuò)展運(yùn)算符、箭頭函數(shù))
  6. 能掌握ES6中模塊化的基本用法(import、export、export default)
  7. 能掌握 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)

  1. 能掌握理解 Express 中間件執(zhí)行機(jī)制并舉例
  2. 能掌握利用 Express 中間件處理網(wǎng)站 404
  3. 能掌握 Express 中間件統(tǒng)一處理全局錯(cuò)誤
  4. 能掌握 Nunjucks 模板引擎的基本使用(布局功能)
  5. 能掌握利用 Express 中間件解析表單 POST 請求體
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內(nèi)容