1. 企业级开发
es6 + 企业级框架vue
1) 项目结构
取决于脚手架(vue-cli)
$ vue create zhaopin
node_modules
public
src
dist()
2) 脚手架中存在静态服务器
$ yarn serve
3) 打包
$ yarn build
4) 项目版本控制
git/svn
5) 部署
2. es6学习环境
linux nodejs vi
1) vi hello.js
2) node hello.js
3. 模块化机制(CommonJS)
1) 模块定义
任意一个js文件或者目录都可以为一个模块
在模块文件中,都有一个module对象表示当前模块
id
filename 路径+文件名
parent 父模块
children 子模块
paths 路径
exports 【模块向外暴露的接口】
2) 模块引用
require("")
参数:
1) 路径
require("./module1")
按照指定的路径加载所需的模块
2) 模块名称
require("module1")
按照paths中的路径依次寻找所需模块,直到找见为止
node_modules
用户存放模块(第三方)
4. npm (node package manager)
$ npm init
在当前目录下产生一个package.json,这个文件是当前模块的核心配置文件,记录 模块的基本信息,依赖信息,脚本信息
$ npm install xxx --save
本地安装xxx模块,默认将xxx安装到当前目录下的node_modules目录中,如果当前目录没有node_modules会自动创建,--save表示这个xxx模块是一个产品依赖,维护在package.json 中的dependecies属性
$ npm install xxx -g
全局安装xxx模块,默认会将xxx安装到node的安装目录中
/opt/node-v10.14.2/lib/node_modules
/opt/node-v10.14.2/bin
/opt/node-v10.14.2/share
效果:
全局安装的模块可以在命令行中直接调用,一般用于命令行工具的安装,比如cnpm,babel-cli,vue-cli,create-react-app的安装
5. cnpm
npm淘宝镜像
1) 安装
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
报错:
EACCES: permission denied, access '/opt/node-v10.14.2/lib/node_modules/cnpm/node_modules/address'
原因:
当前用户是普通用户,但是全局安装需要将第三方依赖安装到/opt/xxx,没有权限!
解决方案:
sudo npm 失败
将
/opt/node-v10.14.2/lib/node_modules
/opt/node-v10.14.2/bin
/opt/node-v10.14.2/share
的拥有者变为当前用户(larry)
$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
$ sudo chown -R larry /opt/node-v10.14.2/{lib/node_modules,bin,share}
2) 使用
使用方式与cnpm完全一致,只不过原先用npm现在用cnpm
6. babel
将es6转换es5,仅仅是语法上的转换,对于功能的增强则无法提供,需要添加babel-polyfill,另外不支持模块化的合并,如果需要合并模块还需要webpack支持。
1) 全局安装babel-cli
$ cnpm install babel-cli -g
$ babel --version
6.26.0 (babel-core 6.26.3)
2) 在项目的根目录中安装bebel预设
$ cnpm install babel-preset-es2015 --save-dev
3) 在项目的根目录中添加.babelrc的配置文件
{
"presets":["es2015"]
}
7. 变量的声明
1) var
可以重复声明
var a = 3; var a = 4;
变量的声明会提升
没有局部作用域
for(var i=0;i<=100;i++){}
console.log(i);
2) let 声明一个变量
不可以重复声明
变量的声明不会被提升,也就是说在变量声明之前不能调用这个变量
具有局部作用域
3) const 声明一个常量
不可以重复声明
变量的声明不会被提升,也就是说在变量声明之前不能调用这个变量
具有局部作用域
常量的值无法改变
const a = 3;
a++;
4) 解构
1. 对象解构
从一个对象或者数组或字符串中【匹配】出来若干个值分别保存到不同变量中
let obj = {
name:"terry",
age:12,
gender:"male"
}
//let {name:name,age:age,gender:gender} = obj;
let name = "charles";
let {name:nn,gender,address} = obj;
console.log(name,nn,address,gender);
let {address:{city}} = {
realname:"larry",
address:{
province:"江西省",
city:"南昌市",
area:"青山湖区"
}
}
console.log(city);
默认值
function get({url,method="get",data={},success}){
console.log('url',url);
console.log('method',method);
console.log('data',data);
console.log('success',success);
}
get({
url:"http://xxx:6677",
data:{id:1},
success:function(){},
method:"delete"
})
2. 数组的结构
let [a,b,c,[d],e] = [1,2,3,[4,5],6,7,8];
console.log(a,b,c,d,e);
3. 字符串解构
let [a,b,c] = "hello";
console.log(a,b,c);
let {length} = "hello"
console.log(length);
console.log("hello".length);
8. 对象拓展
1) 对象字面量的简写形式
var age = 12;
var obj = {
name:"terry",
age:age
}
=简写=>
let name = "terry";
let age = 12;
let obj = {name, age }
2) 对象api拓展
var o = new Object();
o 实例对象
Object o的构造函数
Object.prototype o的构造函数的原型,o的原型对象
o可以调用Object.prototype中的方法,不能调用Object中的方法
Object.prototype.toString
Object.prototype.valueOf
Object.prototype.prototypeOf
Object.prototype.hasOwnProperty
...
ES6对Object这个构造函数进行了拓展
1. Object.is(o1,o2)
对比o1与o2是否相等,如果相等返回true,类似于===
2. Object.assign(target,o1,o2,...)
3. Object.setPrototypeOf(obj,prototype)
=> obj.__proto__ = prototype;
4. Object.getPrototypeOf(obj)
=> obj.__proto__
5. Object.keys()
6. Object.values()
7. Object.entries()
9. 函数拓展
1) 函数简写
1. 函数在对象中
let obj = {
sayName(){
},
sayAge(){
},
foo:()=>{}, //不推荐写法!
bar:function(){}
}
2. 函数在参数中(回调函数)
list.filter(function(item){
return item.gender === "male"
})
等价于
list.filter(item=>item.gender === "male")
等价于
function foo(){
list.filter((item)=>{
//这个箭头函数中的this指向foo中的this
return item.gender === "male"
})
}
let obj = {
data:{
name:"charles",
list:[
{name:"larry",gender:"male"},
{name:"tom",gender:"male"},
{name:"vicky",gender:"female"}
],
boys:[]
},
foo(){
// this指向obj
let that = this;
this.data.list.forEach(function(item){
//this
if(item.gender === "male"){
that.data.boys.push(item)
}
})
},
bar(){
this.data.list.forEach((item)=>{
//箭头函数中的this指向外部函数的this
if(item.gender === "male"){
this.data.boys.push(item);
}
})
}
}
//obj.foo();
obj.bar();
console.log(obj.data.boys);
12. rest操作符
...
剥离、拆分
let o1 = {
a:"1",
b:"2"
}
let o2 = {
c:"3",
d:"4",
e:"5"
}
Object.assign({},o1,o2)
{...o1,...o2}
将字符串转换数组
let str = "hello";
let arr = [...str]
str.split("")
13. 集合的新特性
存放多个值的容器
1) Array
元素有序并且可以重复的即可
Array.from(v)
v为类数组对象或可迭代的对象(具有迭代器的对象)
let al = {"0":"terry","1":"larry","2":"tom",length:3}
console.log(al);
console.log(Array.from(al));
Array.of()
let array = Array.of(2) //[2]
let array = Array.of(2,3,4) //[2,3,4]
Array.prototype.fill()
Array.prototype.includes()
Array.prototype.find(匿名函数)
Array.prototype.findIndex(匿名函数)
查找到第一个符合条件的值进行返回,与filter类似
Array.prototype.keys() 获取遍历key值的迭代器
Array.prototype.values() 获取遍历val的迭代器
Array.prototype.entries() 获取遍历键值对的迭代器
let arr = [
{name:"terry", gender:"male"},
{name:"larry", gender:"male"},
{name:"vicky", gender:"female"}
]
let k_iterator = arr.keys();
// 如何利用k_iterator获取arr中的每个元素
let item ;
while(!(item = k_iterator.next()).done){
let key =item.value;
let val = arr[key];
console.log(val);
}
2) Set
元素无序不可以重复的集合
1. 实例化
let s1 = new Set()
let s2 = new Set([1,2,3,4,1,2])
参数必须是可以迭代的
2. Set.prototype.xxx
size
add(v)
delete(v)
has(v)
clear()
forEach()
keys() 获取值的迭代器
values() 获取值的迭代器
entries() 获取值-值的迭代器
3) Map
键值对,键可以为任意数据类型;与对象对比其特点为key可以为任意数据类型
1. 实例化
let map = new Map();
let map = new Map([["name","terry"],["age",12]])
2. Map.prototype.xxx
size
set(key,val) key值如果相同,后者覆盖前者
get(key)
has(key)
delete(key)
clear()
forEach()
keys()
values()
entries()
3. 典型应用(购物车)
Map {
id:{
id,
name,
price,
number
}
}
加入购物车:
{
id:1,
name:"可口可乐",
price:2.5
number:1
}
先判断购物车中是否具有id为1的key,如果有,修改number,如果没有set
let shopcar = {
car:new Map(),
add(line){
if(this.car.has(line.id)){
this.car.get(line.id).number += line.number;
}else {
this.car.set(line.id,line)
}
},
remove(id){
this.car.delete(id)
},
jiezhang(){
let total = 0;
for(let i of this.car.values()){
total += (i.price * i.number)
}
return total;
}
}
// 首次向购物车中添加可口可乐
shopcar.add({id:1,name:"可口可乐",price:2.5,number:1})
// 再向购物车中添加可口可乐
shopcar.add({id:1,name:"可口可乐",price:2.5,number:1})
// 首次向购物车中添加北京方便面
shopcar.add({id:2,name:"北京方便面",price:1,number:1})
//shopcar.remove(1);
console.log(shopcar.car);
let total = shopcar.jiezhang();
console.log("总额为:",total);
14. 迭代器
用于遍历的统一机制,这种机制允许我们调用next()方法,每次调用都会返回一个对象 {value,done},当完成迭代后done值为true,value每次获取的元素
迭代器的使用
1) 手动使用
let iterator = array.values();
let item ;
while(!(item = iterator.next()).done){
console.log(item.value);
}
2) 使用for-of协助
let iterator = array.values();
for(let v of iterator){
console.log(v);
}
3.使用for-of直接遍历可以迭代对象
for(let v of array){
console.log(v);
}
谁具有迭代器?
Array
Set
Map
String
类数组对象 Arguments NodeList
4. 如何将一个普通对象变成一个可以迭代的对象
let obj = {name:"terry",age:12}
// 如何获取一个迭代器
obj[Symbol.iterator] = [][Symbol.iterator]
// 将对象转换为set
new Set(obj)
15. entry
[[key,val],[key,val],...]
16. 迭代器是如何添加到Set、Map、Array...这些数据结构上的?
var o = {
name:"terry",
}
o.iterator = iterator;
o.iterator = "hello"
Symbol()
这个函数可以产生一个特殊符号,这个符号可以用于key,通过这个key找见对应的函数。这个key好处在于它是隐式的。
17. Promise
构造函数,用于创建一个承诺对象,承诺对象主要用于封装异步操作。
承诺发起
承诺成功 resolved
承诺失败 rejected
1) 获取或者创建一个承诺对象
let promise = new Promise(function(resolve,reject){
})
resolve 方法, 将承诺对象 pending -> resolved
reject 方法, 将承诺对象 pending -> rejected
2) 使用承诺对象
Promise.prototype.then(successHandler[,errorHandler])
successHandler 当承诺成功的时候执行
errorHandler 当承诺失败的时候执行
一般不再then方法中添加errorHandler,而是将errorHandler放到catch中
返回值为当前promise实例
Promise.prototype.catch(errorHandler)
errorHandler 当承诺失败的时候执行
Promise.prototype.finally(handler)
handler 不管承诺对象的状态变为什么样子,这个handler函数都会执行
3) 高级特性
1. Promise.all([p1,p2,...])
将多个承诺对象合并为一个承诺对象,返回值为promise
promise
.then((result)=>{
//当所有的承诺都resolved的时候该回调函数才会执行
// result 为每个承诺对象返回值组成的一个数组
})
.catch(()=>{
//当有一个承诺对象rejected就会执行这个回调函数
})
当查询出所有顾客信息以及订单信息后打开模态框
2. Promise.race([p1,p2,...])
谁先执行完就是谁,返回值为promise
promise
.then((result)=>{
/先执行完的
})
.catch(()=>{
//只要有一个承诺对象的状态变为rejected,就会执行该回调函数
})
3. Promise.resolve(v)
将v转换为承诺对象
4. Promise.rejected(v)
返回一个状态为rejected的承诺对象
// 基于回调函数的封装
get({url,success,error}){
let xhr = new XMLHttpRequest();
xhr.open("get",url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.responseType = "json"
xhr.send();
xhr.onreadystatechange = function(){
if(this.readyState === 4){
if(this.status === 200){
//请求成功
success(this.response)
} else {
//请求失败
error(this)
}
}
}
}
get({
url:"",
success:function(){
},
error:function(){
}
})
18. Generator函数(用于产生一个迭代器对象
)
Promise封装了异步操作
$.get("/customer/findAll")
.then((response)=>{
//通过回调函数来获取异步操作的结果
})
1) 声明
function* foo(){
let a = “hello”
yield a;
yield “world”;
return “end”
}
yield必须在generator函数中
2) 调用
let iterator = foo();
iterator.next() // {value:“hello”,done:false}
iterator.next() // {value:“world”,done:false}
iterator.next() // {value:“end”,done:true}
3) this
Generator与普通函数中的this的获取是一致的
4) yeild表达式的返回值
默认是没有返回值的
iterator.next(参数)
当前这个参数为上一个yield表达式的返回值
5) 作用:
1. Generator函数可以用于调用异步函数,将异步操作同步化
let customers = $.get("/customer/findAll");
let customerId = customers[0].id
let address = $.get("/address/findByCustomerId?id="+Id)
2. 迭代器
将obj转换为可迭代器的对象
obj[Symbol.iterator] = ""[Symbol.iterator]
Generator的返回值就是迭代器对象
let arr = [1,2,3];
arr.values() 迭代器对象
arr[Symbol.iterator] 生成迭代器对象的函数
课堂代码:
let obj = {"0":"terry","1":"larry","2":"tom"}
obj[Symbol.iterator] = function* (){
//完成迭代obj的工作
for(let key in this){
let val = this[key];
yield [key,val];
}
}
19. Async函数
是Generator函数的语法糖
async function foo(){
let customers = await $.get(url)
let orders = await $.get(url)
}
let promise = foo()
1) await
await表达式后一般为promise,await会等待promise状态改变resolved,然后将请求结果返回,最后继续向下运行
通过id删除顾客信息
function deleteById(id){
$.get(deleteById).then(()=>{
alert("");
$.get(findAll).then(()=>{
重新渲染
})
})
}
async版本
```javascript
async function deleteById(id){
let result = await(deleteById,id);
alert(result.message);
await(findAll)
}
deleteById(1)
20. axios
基于promise机制的纯粹的ajax框架
0) 特点
基于Promise
运行在nodejs、浏览器
自动转换request,response data(默认将请求数据转换为json)
Content-Type:"application/json"
拦截器
1) ajax解决方案
1) XMLHttpRequest
原生的ajax
2) jQuery.ajax()
不涉及到数据驱动框架的时候使用
3) axios
涉及到数据驱动框架的时候
react/vue/angular + axios
在nodejs中可以使用
2) 导入依赖
1) 浏览器
2) nodejs
npm install axios --save
3) axios底层接口
axios({
url,
method,
data, // post请求的参数
params, // get请求的参数
baseURL, // 基础路径
responseType:'json', //要求服务器端返回值类型为json
transformRequest:[function(data,headers){
return data;
}], //在请求发送到服务器前可以改变data
transformResponse:[function(data){
return data;
}], //在响应数据到达then或者catch之前允许修改
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type':"application/json"
}, //异步操作
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
}, // get请求中,序列化params的函数,默认如上
get请求中的params一般用查询字符串
timeout:0, //超时设置,默认不设置
withCredentials:false, // 设置是否携带浏览器cookie
proxy:{
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
}, //代理
xsrfXXX, //
})
axios(config) 返回值为promise对象
4) axios快捷接口
axios.get(url[,config])
axios.get(url+"?id="+id)
axios.get(url,{params:{id}})
axios.post(url[,data][,config])
axios.post(url,{name:"terry"})
5) Response Schema
axios请求成功或者失败后默认会将服务器端的返回结果封装到一个新的对象,这个对象的数据结构:
{
data: {},
status: 200,
statusText: 'OK',
headers: {},
config: {},
request: {}
}
6) 配置默认信息
axios有一个属性defaults,在这个对象中配置的属性所有的axios对象都可以应用到
axios.defaults.baseURL = "http://134.175.100.63:6677"
axios.defaults.transformRequest = []
axios.defaults.transformResponse = []
axios.defaults.timeout = 10000;
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
axios.defaults.headers.common["Content-Type"] = "application/x-www-form-urlencoded";
axios.get("/customer/findAll")
.then()
axios.get("/order/findAll")
.then()
axiox.post(url,data)
默认情况下data对象转换为json
7) 拦截器
与transformRequest,transformResponse功能类似,可以在请求发送之前或者响应回来之后执行特定代码。但是transformRequest,transformResponse主要用于对参数的格式化或者是对响应结果的格式化,而拦截器主要用于业务上面的拦截,主要可以用于日志的记录,或者异常响应的统一处理...
1. 请求拦截器
axios.interceptors.request.use(function (config) {
// 在请求发送之前可以配置config
// ...
return config;
}, function (error) {
// 在请求出现异常的时候,默认返回失败的承诺
return Promise.reject(error);
});
2. 响应拦截器
axios.interceptors.response.use(function (response) {
// 一般在这里可以对响应结果进行处理
// response.data 才是后台返回的结果剃
return response;
}, function (error) {
// 提示异常信息
return Promise.reject(error);
});
21. 类
构造函数 = 类
类是构造函数的语法糖
1) es5构造函数
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.prototype.sayName = function(){
console.log("my name is",this.name);
}
Animal.prototype.sayAge = function(){
console.log("my age is",this.age);
}
//继承
function Dog(name,age,gender){
Animal.call(this,name,age)
this.gender = gender;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.protype.sayGender = function(){
console.log("my gender is",this.gender);
}
let d = new Dog("一休",2,"male");
d.sayName()
d.sayGender();
2) 语法
1. 类的声明
class 类名 {
constructor(构造函数形式参数){
this.xxx = xxx;
}
xxx(){
}
yyy(){
}
}
this表示当前构造函数的实例对象
2. 类的继承
class 子类名 extends 父类名 {
constuctor(子构造函数形式参数){
super(x,y)
this.z = z;
}
}
任意一个类如果你不提供构造函数,那么系统会为你自动分配一个构造函数,这个构造函数如下
constructor(a,b,c){
super(a)
}
super 是借用构造函数的语法糖
3) this
不管是构造函数还是普通方法,this都指向当前类的实例对象
22. ES6的模块化
1) CommonJS模块化
module.exports = 暴露接口
require(模块名称/路径)
2) ES6模块化
export 暴露的接口
import {} from "模块名称/路径"
1. 定义模块,通过export暴露接口
module1.js
export let a = 3;
export function sayHello(){
}
index.js
import {a,sayHello} from './module1'
2. 定义模块,通过export default 暴露接口
module1.js
let a = 3;
function sayHello(){
}
export default {
a,
sayHello
}
index.js
import module1 from './module1'
module1.sayHello
3. nodejs如何支持es6的模块化
1) es6->es5
4. 案例:
```javascript
module1.js
let name= "module1";
// 单独暴露
export function sayName(){
console.log("my name is",this.name);
}
export function sayHello(){
console.log("hello world");
}
index.js
import {sayName} from './module1'
5. 案例
module1.js
let name= "module1";
function sayAge(){},
function sayGender(){}
// 默认集体暴露
export default {
sayAge,
sayGender
}
index.js
import m from './module1'
m.sayAge()