11.函数拓展
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)=>{
//只要有一个承诺对象的状态变为resolved,就会执行该回调函数
})
.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"
}
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版本
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
2) jQuery.ajax()
不涉及到数据驱动框架的时候使用
3) axios
涉及到数据驱动框架的时候
react/vue/angular + axios
在nodejs中可以使用
2) 导入依赖
1) 浏览器
<script></script>
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的函数,默认如上
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.prototype.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. 案例:
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()
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。