1)解构赋值
数组解构
let [a,b,c]=[1,2,3];
console.log(a,b,c);//1 2 3
交换
let a=1,b=2,c=3;
[a,b]=[b,a];
console.log(a,b);//2 1
冒泡
let arr=[1,2,1,5,4,8,9,7,8,5,6];
for (let i=0;i<arr.length;i++){
if(arr[i]>arr[i+1]){
[arr[i],arr[i+1]]=[arr[i+1],arr[i]]
}
}
ES5中不允许设置参数初始值
ES6中允许这种情况
当设置了参数初始值,如果这个参数没有赋值,就会默认初始值
function fn(a,b=4){console.log(a,b)};
fn(3,5);//3,5
fn(3);//3,5
解构赋值时变量设置了初始值0
如果给一个赋值,b就是5
如果没有给赋值,b的初始值就是0
let [a,b,c]=[3,5];//3 5 0
let [a,b=0]=[3];//3 0
console.log(a,b);
function fn([a,b=0]{console.log(a,b)})
fn([4,3]);//4 3
fn([4]);// 4 0
对象的解构赋值
let {a,b}={a:1,b:2};
console.log(a,b);//1 2
对象的解构赋值与顺序无关
没有该属性是无法解构赋值的
let {a,c}={b:3,a:1};
console.log(a,c);//1 undefined
对象解构必须按照结构解构
let {a,b}={a:5,b:{a:6}};
console.log(a,b);//5 {a:6}
如果解构是属性名有重复,可以在属性名使用:新名称来解构
let {a,b:{a:a1}}={a:5,b:{a:6}};
console.log(a,a1);//5,6
再看一个
let {p:[x,{y,z=3}]}={p:["Hello",{y:"World"}]};
console.log(x,y,z);// Hello World 3
升级一下
let obj={a:1,b:{a:2,b:{a:3,b:{a:4}}}};
let {a,b:{a:a1,b:{a:a2,b:{a:a3}}}}=obj;
console.log(a,a1,a2,a3);//1 2 3 4
多个
let [{a:z1,b:[{a:z2,b:z3}]},{a:z4,b:[{a:z5,b:z6}]}]=[{a:1,b:[{a:2,b:3}]},{a:4,b:[{a:5,b:6}]}];
console.log(z1,z2,z3,z4,z5,z6);//1 2 3 4 5 6
字符串解构
let str="abcdef";
let {length}=str
console.log(length);//6
Math的解构
let {random,max,min}=Math
let a=random();
let b=max(3,5,8);
let c=min(3,5,8);
console.log(a,b,c);//a随机值 max最大值8 min最小值3
在对象中如果方法中有this这种方法不能被解构
let {ce,randomColor}=Utils;
let div=ce("div");
let color=randomColor();
console.log(div,color);//报错
JSON
JSON是一种字符串格式
JSON字符串的特征就是所有属性名都是用“”因起来的,最外层是单引号
let str='{"a":1,"b":{"c":"abc","d":true}}';
JSON.parse(JSON格式字符串) 解析转换为对象
JSON.stringify(对象) 对象转为JSON字符串
深复制
let obj={a:1,b:2,c:{a:1,b:2}};
let o=JSON.parse(JSON.stringify(obj));
这样可以完成对象的深复制
对比数组内数据是否相同
let arr=[2,4,6,8];
let arr1=[8,4,6,2];
console.log(JSON.stringify(arr.sort())===JSON.stringify(arr1sort()));
2)symbol
数据类型
字符型 数值型 布尔型 undefined 空值
object 复杂类型
第七种类型 symol
let a=Symbol("a");
let b=Symbol("abc")
let c=Symbol("c")
console.log(a==b);//报错
不能用于任何运算
function getSymbol(s){
return s.toString().match(/^symbol((.*?))$/)[1];
}
console.log((getSymbol(a)));//a
console.log((getSymol(b)));//abc
symbol使用场景
let state="";
const RUN="run";//对照组
const WALK="walk";//对照组
const PLAY="play";//对照组
去除魔术字符串
const RUN=Symbol("run");
const WALK=Symbol("walk");
const PLAY=Symbol("play");
let bns=Array.from(document.querySelectorAll("button"));
let div=div=docement.querySelector("div");
bns.forEach(item=>{
item.addEventListener("click",clickHandler);
});
div.addEventListener("click",divclickHandler);
setInterval(animation,1000);
function divclickHandler(e){
state=Symbol("run");
}
function clickHandler(e){
let index=bns.indexOf(this);
state=index===0 ? RUN : (index ===1 ? WALK : PLAY)
}
function animation(){
swiych(state){
case RUN:
console.log("run");
break;
case WALK:
console.log("walk");
break;
case PLAY:
console.log("play");
break;
}
}
3)set和map
let arr=[1,2,3,4,5,6,6];
let obj={a:1,b:2,c:3};
数组数据类型
数组无名有值
根据下标记录数据 按照顺序记录
如果需要找到某个数据,必须遍历整个数组,查找数据 时间长
插入,删除,添加元素 因为数组是紧密结构 时间长
数组的元素可以重复,无法让元素唯一性
数组有关联关系,可以根据自身前后找到上下数据
数组可以知道当前遍历到什么地方了
对象数据类型
key:value 键值对 必须要有属性名
可以直接根据键名获取到值,不需要遍历 速度快
键名是唯一,如果有相同键名会覆盖,但是值依然不是唯一
如果查找值 依然需要遍历整个对象查找 时间长
插入,删除,添加元素,对象本身是一个松散型结构,因此插入等操作没有关联关系,速度非常快
因为松散结构,不具备上下数据
对象是没有长度,所以无法知道现在遍历到第几个,是不是最后一个,是不是开始
set
set 类型是一个没有重复元素的列表
let a=new Set([1,2,3,4,5,6]);
//列表容器,没有下标
//添加元素
a.add(6);
Set类型是一个没有顺序的列表,各数据之间没有关联
console.log(a.has(2));//判断有没有这个元素,不需要遍历 快速
a.delete(3);//删除元素3 删除速度快
a.clear();//清除这个列表 速度快
console.log(a);//""
数组去重
let arr =[1,3,2,4,5,6,4,4,5];
arr=Array.from(new Set(arr));
console.log(arr);
弱引用类型列表 只能添加对象类型数据
let b=new WeakSet();
map
let b=new Map();
b.set("name","root");
b.set("age",30);
b.set("sex","man");
Map类型是有长度的键值对数据类型
console.log(b.size);
可以根据键查找到属性
console.log(b.get("age"));
删除属性
b.delete("sex");
清空所有
b.clear();//清除所有属性,快速删除所有属性值
只能判断是否有键名,不能判断是否有这个值
console.log(b.has("age"));//true
遍历属性名
//遍历value值
for (let prop of b.values()){
console.log(value);
}
//遍历key值
for (let key of b.keys()){
console.log(key);
}
全都要
b.forEach(function(prop,value){
console.log(prop,value);
});
弱引用键值对数据
let c=new Weakmap();
c.set();
4)生成器函数
生成器函数的具体使用环境 以后讲
生成器函数return结果并不能直接执行函数后返回
function* fns(a,b){
yield a;
a++;
yield a;
yield b;
b++;
yield b;
let s=a+b;
return s;
}
let a=fns(5,10);
let value=a.next();//5
value=a.next();//6
value=a.next();//切换到b 10
value=a.next();//11
value=a.next();//11
value=a.next();//17
console.log(value);
生成器函数yield表示步长,每一步都会储存之前的数据
next表示执行下一个步长,也就是下一个yield并获取或者切换参数并调用
5)面对对象基础
面向过程
按照用例的顺序一步步执行的程序过程,叫做面向过程
用例,用户操作的实例
面向对象
任何事物都属于对象,因此我们将所有事物归类设置,根据类别创建不同对象
根据这些不同的对象组合完成整个项目
类别 对象
类别是一种抽象的概念 对象是根据类别实际创建出来的案例
把根据类别创建出案例的过程叫做实例化对象
class Human{
head=1;
eyes=2;
body=1,
makeFire(){
console.log("生火")
}
love(){}
run(){console.log("跑步")}
}
实例化对象
let 对象=new 类别();//实例化对象
let eric=new Human();//继承 子类
let boa=new Human();//继承 子类
console.log(eric.head);//子类拥有父类方法
console.log(boa.body);//子类拥有父类方法
eric.makeFire();//子类可以调用父类方法
boa.run();//子类可以调用父类方法
console.log(eric,boa);//和父类几乎一样
继承的关系
父类 当前类继承所有类别都是它的父类
子类 继承当前类形成的新类别就是当前类子类
超类 子类的父类叫做超类
面对对象完成
若干个小方块,颜色不同,一起向右运行,
点击一个小方块,就会停止,再点击继续前进,每个方块直接不会互相影响
clas Rect{
box;
bool=false;
x=0;
constructor()
{
this.box=this.createElem()
}
//函数方法
createElem(){
let div=document.createElement("div");
div.style.width="50px";
div.style.height="50px";
div.style.position="absolute";
div.style.backgroundColor=this.randomColor();
div.addEventListener("click",e=>this.clickHandler(e))
return div;
}
randomColor(){
let color="#";
for(let i=0;i<6;i++){
color+=Math.floor(Math.random()*16).toString(16);
}
return color;
}
appendTo(parent){
if(typeof parent==="string"){
parent=document.querySelector(parent);
}
parent.appendChild(this.box);
}
clickHandler(e){
this.bool=!bool;
}
update(){
if(this.bool) return;
this.x+=2;
this.box.style.left=this.x+"px";
}
}