解构赋值,就是快速的从对象或者数组或字符串中取出成员的一个语法方式
解构对象
快速的从对象中获取成员
// ES5的方法向得到对象中的成员
const obj = {
name: 'kerwin' ,
age: 100,
gender: '男'
}
let name = obj.name
let age = obj.age
let gender = obj.gender
//解构赋值的方式从对象中获取成员
const obj = {
name: 'kerwin',
age: '100',
gender: '男'
}
let {name,age,gender}=obj;
let myname = "kerwin"
console.log(myname . includes("e")) //true
console.log (myname . startswith("k")) //true
console.log(myname . endswith("n")) //true
let myname = "kerwin"
、
console.log(myname. repeat(3)) //kerwinkerwinkerwin
console.log(myname . repeat(0)) //""
console.log (myname . repeat(3.5)) //kerwinkerwinkerwin
console.log(myname . repeat("3"))//kerwinkerwinkerwin
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
let num1 = Number. isFinite(100) //true
let num2 = Number. isFinite(100/0) //false
let num3 = Number. isFinite(Infinity) // false
let num4 = Number. isFinite("100") //false
let num1 = Number. isNaN(100) // false
let num2 = Number. isNaN(NaN) //true
let num3 = Number . isNaN("kerwin") //false
let num4 = Number. isNaN("100") // false
它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一 律返回false,Number.isNaN)只有对于NaN才返回true,非NaN一律返回false。
let num1 = Number. isInteger(100) //true
let num2 = Number. isInteger(100.0) //true
let num3 = Number. isInteger("kerwin") //false
let num4 = Number . isInteger("100") //false
function isEqual(a,b){
return Math.abs(a-b)<Number . EPSILON
}
console.log(isEqual(0.1+0.2,0.3)) //true
console.log(0.1+0.2===0.3) //false
console.log(Math. trunc(1.2)) //1
console.log(Math. trunc(1.8)) //1
console.log(Math. trunc(-1.8)) //-1
console.log(Math.trunc(-1.2)) //-1
Math. sign(-100) // -1
Math. sign(100) // +1
Math. sign(0) // +0
Math. sign(-0) // -0
Math. sign("kerwin") // NaN
let arr1 = [1,2,3]
let arr2 = [4,5,6]
console.log([...arrl,...arr2])
function test(){
console.log(Array. from(arguments))
}
test(1,2,3)
let oli = document. queryselectorAll("li")console.log(Array. from(oli))
let arr1 = Array(3)
console.log(arr1)// [,,]
let arr2 = Array.of(3)console.log(arr2)// [3]
ES6引入了一种新的原始数据类型 symbol,表示独一无二的值。它属于JavaScript语言的原生数据类型之一,其他数据类型是:undefined、 null、 布尔值(Boolean) 、字符串(String) 、数值(Number)、对象 (Object) 。
let name = Symbol()//生成了一个symbol类型数据
let age = Symbol()
var obj ={
[name]:"kerwin",
[age] :100
}
let name = Symbol("name ")
let age = Symbo1("age")
var obj={
[name]: "kerwin",
[age] :100
}
console.log(obj)
var obj ={
[symbol. for("name ")]: "kerwin",
[symbol. for("age ")]:100
}
console.log(obj[symbol.for("name")])
注:
Iterator的作用有三个:
一是为各种数据结构, 提供一个统一的、 简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是ES6创造了一种新的遍历命令for…of循环,lterator 接口主要供for…of循环
let arr = ["kerwin", "tiechui", "gangdaner"]
for(let i of arr){
console.log(i)
}
Iterator的遍历过程是这样的。
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
let i = arr[symbol. iterator]()
console.log(i. next())
console.log(i. next())
console.log(i. next())
console.log(i. next())
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是"可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。
原生默认具备Iterator接口的数据结构如下。
如何对于对象进行for fo遍历?
let obj ={
0: "kerwin",
1: "tiechui",
2: "gangdaner",
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
}
for(let i of obj) {
console.log(i)
}
let obj2 = {
data: ['kerwin', 'tiechuiI, "gangdaner"],
[Symbol. iterator](){
//let _this=this
let index=0;
return {
next:()=>{
if (index < this. data.1ength)
return {
value: this. data[index++],
done: false
}
}else{
return {
value: undefined,
done: true
}
}
}
}
}
for (let i of obj2) {
console. log(i)
}
它类似于数组,但成员的值都是唯一的, 没有重复的值。
let s1 = new Set([1, 2,3, 2,3])
console. log(s1)
let s2 = new Set()
s2. add(1)
s2. add(2)
s2. add(3)
console.log(s2)
类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
let m1 = new Map()
m1.set("name", "kerwin")
m1.set({a:1},"大连")
console. 1og(m1)
let m2= new Map([
["name","kerwin"],
[{a:1},"大连"]
])
console.log(m2)
Proxy如其名,它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值,以及实例化等等多种操作,都会被拦截住, 经过这一层我们可以统一处理, 我们可以认为它就是"代理器"
let target = {}
let proxy = new Proxy(target,{
get(target, prop){
return target[prop]
}
})
Proxy本质上属于元编程非破坏性数据劫持,在原对象的基础上进行了功能的衍生而不影响原对象,符合松耦合高内聚的设计理念
Reflect可以用于获取目标对象的行为,它与Object类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与Proxy是对应的。
const obj = {
};
Reflect. defineProperty(obj, 'name', {
value: 'kerwin',
writable: false ,
configurable:fa1se
});
//老写法
try {
Object. defineProperty(target, property, attributes);
// success
} catch (e) {
// fail
}
//新写法
if (Reflect. defineProperty(target, property, attributes)) {
// success
} e1se {
// fail
}
const obj = {
name : "kerwin"
};
//老写法
console.log("name" in obj) //true
//新写法
console.log(Reflect. has(obj,'name')) //true
//老写法
delete obj . name
//新写法
Reflect. deleteProperty(obj, "name")
let target = new Set()
const proxy = new Proxy(target, {
get(target, key) {
const value = Reflect . get(target ,key)
// 遇到Function都手动绑定一下this
if (value instanceof Function) {
console.log(`访问${value}方法了`)
return value. bind(target)
//不能 是 call apply
}
return value
},
set() {
return Reflect. set(...arguments)
}
})
proxy. add(1)
let arr=[1,2,3]
let proxy = new Proxy(arr,{
get(target, key) {
console.log('get', key)
return Reflect. get(...arguments)
},
set(target, key, value) {
console. log('set', key, value)
return Reflect.set(...arguments)
}
})
proxy . push(4)
//能够打印出很多内容
//get push (寻找proxy.push 方法)
//get length (设置当前的length)
//set 3 4(设置proxy[3]=4)
//set length 4 (设置proxy. length = 4)
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
Promise.all
Promise.race
语法:
new Promise(function (resolve, reject) {
// resolve表示成功的回调
// reject表示失败的回调
}). then(function (res) {
//成功的函数
}). catch(function (err) {
// 失败的函数
})
Promise对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。
异步操作未完成(pending)
异步操作成功(fulfilled)
异步操作失败(rejected)
这三种的状态的变化途径只有两种。
从“未完成”到“成功”
从“未完成”到“失败”
一旦状态发生变化, 就凝固了,不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。
因此,Promise 的最终结果只有两种。
异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled.
异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。
Generator函数是ES6提供的一种异步编程解决方案
Generator函数是一个状态机, 封装了多个内部状态。
执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。
function *gen(){
console. log(1)
yield;
console. log(2)
yield;
console. log(3)
}
let g = gen()
g.next()
g.next()
g.next()
yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。
手动版本
function *gen() {
let res1 = yield ajax("1. json")
console.log(res1)
let res2 = yield ajax("2. json")
console.log(res2)
}
let g = gen()
g. next(). value. then(data=>{
g. next(data). value. then(data=>{
g. next(data)
})
})
自动版本
function* gen() {
let res1 = yie]d ajax("1. json")
console. log(res1)
let res2 = yie1d ajax("2. json")
console. log(res2)
}
function AutoRun(gen) {
let g = gen();
function next(data) {
let res = g.next(data);
if (res. done) return
res. value. then(function (data) {
next (data);
});
}
next();
}
AutoRun(gen) ;
class Person{
constructor(name ,age){
this. name = name;
this.age = age;
}
sayOf(){
console.log(this. name , this. age)
}
}
let obj = new Person("kerwin" ,100)
console.log(obj)
模块化
异步加载
私密不漏
重名不怕
依赖不乱
JavaScript现在有两种模块。一种是ES6模块,简称ESM;另一种是CommonJS模块,简称CJS
Common]S模块是Node.js专用的,与ES6模块不兼容。语法上面,两者最明显的差异是,CommonJS模块使用require()和module. exports , ES6模块使用import和export.
ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
写法1:
export default A1
import a1 from "./1.js"
写法2:
export {A1,A2}
import {A1,A2} from "./1.js"
import {Al as a1,A2 as a2} from "./1.js"
import * as obj from "./1.js"