<script type="module"> // 模块开发,自动严格模式 <script> "use strict";//严格模式 // 变量必须定义后使用 var a=4; function abc(){ var a=3; console.log(window.a); } abc();//4 console.log(window.a); //4 // 不允许参数名重复 function fn(a,a){ console.log(a); } fn(3,5); //Duplicate parameter name not allowed in this context var div=document.querySelector("div"); div.style.width="100px"; div.style.height="100px"; div.style.backgroundColor="red"; div.style.border="1px solid #000000"; // 严格模式不允许使用with with(div.style){ width="100px"; height="100px"; backgroundColor="red"; border="1px solid #000000"; } // 只读属性都不是能修改 div.offsetLeft=300; var str=""; str.length=0;//都不能更改 var obj={}; Object.defineProperty(obj,"a",{ writable:false//只读属性 }) obj.a=10; //报错 // var num=0xFF; // var num=065;//严格模式八进制不能使用 // 不能删除不可删除的属性 var arr=[1,2]; delete arr.length; var obj={} Object.defineProperty(obj,"a",{ configurable:false//不可删除属性 }); delete obj.a; var obj1={}; var obj2={}; var obj3={}; var obj4={}; // 反射 将字符串反射为该字符串变量名的对象 for(var i=1;i<5;i++){ eval("obj"+i).a=i*10; } console.log(obj1,obj2,obj3,obj4) for(var i=0;i<6;i++){ eval("div"+i).innerHTML=i; } // eval 和 arguments 不能重新赋值 //arguments.callee 不能使用 //arguments.callee.caller 不能使用 function abc(){ // 在顶层函数中this不能执行window了,是undefined console.log(this); } abc(); //undefined
let&const
var a=3; for(var i=0;i<10;i++){ } let a=3; console.log(a);//3 for(let i=3;i<10;i++){ // 仅属于这个语句块中 } function fn(){ console.log(a);//3 // console.log(i);//i is not defined if(a>2){ let b=10;//范围仅在if中 } // console.log(b);//b is not defined } fn(); // let定义的变量仅在{}作用域内使用 // var 和 let可以混合使用 // const 常量 const EVENT_ID="event_id"; // 常量不可以修改值 const EVENT_ID;//不能这样 const obj={a:1,b:2}; obj={a:4,b:5};//这样做可以防止obj的引用地址发生改变 obj.a=10; obj=null;//会一直存在堆中,无法销毁
箭头函数
var fn=()=>{ var a=3; var b=4; return a+b; } var sum=fn(); console.log(sum);//7 var fn=function(){ var a=3; var b=4; return a+b; } // 如果函数中仅有一句话,并且这句话是return返回可以省略{}和return var fn=(a,b)=>a+b; var fn=function(a,b){ return a+b; } var arr=[1,2,3,4,5]; // 箭头函数中如果仅有一个参数可以省略小括号 // 如果没有参数,或者由一个以上的参数不能省略小括号 if(arr.every(item=>item>0)){ } var bool=arr.every(function(item){ return item>0 }); if(bool){ } var arr=arr.filter(item=>item>3); console.log(arr); var sum=arr.reduce((value,item)=>value+=item); console.log(sum); arr.sort((a,b)=>b-a); console.log(arr); setInterval(()=>{ },16) var obj={ a:function(){ // ES5的方法 console.log("a") }, b(){ // ES6的方法 console.log("b"); }, c:()=>{ // ES6箭头函数 console.log("c"); } } obj.a(); obj.b(); obj.c(); document.addEventListener("click",e=>{ }) // 更改this指向 var obj={ b:1, a:function(){ document.obj=this; document.addEventListener("click",this.clickHandler); }, clickHandler(e){ console.log("a"); document.removeEventListener("click",this.obj.clickHandler); } } var obj={ b:1, a:function(){ document.obj=this; // var fn=(e)=>{ // console.log(this);//当函数换为箭头函数时, // // this将会被指向当前函数外this的指向 // this.clickHandler(e); // } // var fn=function(e){ // console.log(this);//点击的事件对象 // } // document.addEventListener("click",fn); document.addEventListener("click",e=>this.clickHandler(e)); this.c(); }, clickHandler(e){ console.log(this);//obj // e.currentTarget document.removeEventListener("click",this.clickHandler); }, c:function(){ console.log(this);//调用这个函数的对象,obj }, d:()=>{ console.log(this);//只想这个箭头函数外的this,是这个对象 } } obj.a();//obj这个对象 obj.c();//obj这个对象 obj.d();//window(使用箭头函数后,this指向该函数外的this指向) // 箭头函数主要可以作为改变函数中this的指向问题 var obj={ a:1, init:function(){ var bn=document.querySelector("button"); bn.addEventListener("click",this.fn=e=>this.clickHandler(e)); }, clickHandler:function(e){ console.log(this.a); e.currentTarget.removeEventListener("click",this.fn); } } obj.init(); Utils.dragElem(document.querySelector("button"));
解构赋值
var {a,b}={a:1,b:2}; var [c,d]=[3,4]; var arr=[2,3,4]; var [a,b,c]=arr; console.log(a,b,c); // 函数返回多个元素,解析 function fn(){ var a=1; var b=2; var c=3; a++; b--; c+=4; return [a,b,c]; } var arr=fn(); console.log(arr);//[2,1,7] var [a,b,c]=fn(); console.log(a,b,c); //2 1 7 // 可以让参数赋初值 function fn([a,b,c=3]){ console.log(a,b,c); } fn([1,2]); var [a,b,c=3]=[5,6]; var [a,b,c=3]=[5,6,7]; console.log(a,b,c); function fn(a,b,c=3){ console.log(a,b,c); } fn(3,5); // 数组解析最重要的是按位解析 // 对象是按照属性名解析 // var {a,b,c}={b:10,a:20,c:30}; // console.log(a,b,c);//20 10 30 // var {a,b,c:{a:a1,b:b1}}={a:10,b:20,c:{a:30,b:40}}; // var {a,b=100,c:{a:a1,b:b1=200}}={a:10,c:{a:30}}; // var {a,b=100,c:{a:a1,b:b1=200}}={a:10,c:{a:30,b:40}}; // console.log(a,b,c,a1,b1) //10 20 30 30 40 //10 100 30 30 200 //10 100 30 30 40 //C不能被解构 function fn(){ var a=1; var b=2; var c=3; return {a:1,b:2,c:3}; } var {a,b,c}=fn(); console.log(a,b,c); //1 2 3 // 参数解构赋值后可以跳位,不需要按照顺序写 function fn({a,b=3,c}){ console.log(a,b,c); } fn({a:10,c:20}); //10 3 20 // 将加载进来的对象中方法解构出来形成全局的函数(对象内部的this将被重新指向全局的this) //当对象的函数用到this,不用使用解构,解构会破坏this指向 var {randomColor,ce}=Utils; console.log(randomColor()); ce("div",{"50px",height:"50px",backgroundColor:randomColor()},"body"); // JSON解析 // var x=3; // var y=4; // [x,y]=[y,x];
字符串扩展方法
var str="u4e00";//不可以组合 console.log(str); var div=document.querySelector("div"); var num=0x4e00; setInterval(animation,500); function animation(){ // div.innerHTML=`u${a}` num++; div.innerHTML=String.fromCharCode(num); } var str="ashdjsahdwi"; console.log(str.indexOf("j")>-1); console.log(str.search(/j/)>-1); console.log(str.match(/j/)); console.log(/j/.test(str)); // 判断字符在字符串中是否存在 console.log(str.includes("j")); console.log("abcde".startsWith("a"));//判断a是不是从头开始 console.log("abcde".startsWith("b",1));//判断从第1位开始的是不是b console.log("car_0".startsWith("car_")); console.log("abc_car".endsWith("_car")); console.log("abc_car".endsWith("a",1)); console.log("ab".repeat(3)); 字符串重复 document.documentElement.style.backgroundColor="#"+(Math.floor(Math.random()*256).toString(16)).repeat(3); // 字符串.padStart(长度,前面补充的字符); // 字符串.padEnd(长度,后面补充的字符); console.log("#abcde".padStart(7,Math.floor(Math.random()*16).toString(16))); console.log("#abcde".padEnd(7,Math.floor(Math.random()*16).toString(16))); console.log("#"+Math.floor(Math.random()*0xFFFFFF).toString(16).padStart(6,0)) var a=4; console.log(`abc${a}`); var age=30; console.log(`小明今年${age}岁了!`);//php的语法移植了 // "小明今年{$age}岁了!" alert `123`; function fn(a){ console.log(a); } fn `3`;
Symbol
//Symbol 唯一,创建的永远没有相同的 var a=Symbol("a"); var b=Symbol("b"); var c=Symbol(); console.log(a.toString()); // 去除魔术字符串 //const RUN="run"; //const WALK="walk"; //const STAND="stand"; //const JUMP="jump"; const RUN=Symbol(); const WALK=Symbol(); const STAND=Symbol(); const JUMP=Symbol(); var actorStatus=RUN; // var actorStatus="walk"; actorAction(); function actorAction() { switch (actorStatus) { case RUN: console.log("执行跑的动画"); break; case WALK: console.log("执行走的动画"); break; case STAND: console.log("执行站立的动画"); break; case JUMP: console.log("执行跳跃的动画"); break; } } var obj={ a:1, b:2 } obj.c=10; obj.c=20; // 对象键值对中键可以是字符型也可以是Symbol型 var a="abc"; const KEY_1=Symbol(); var obj={ [a]:10, [KEY_1]:100 } // 这个键名就不会被覆盖 console.log(obj[KEY_1]); obj.abc=200; console.log(obj);
Set和Map
var ab=new Set([1,2,3,4]); console.log(ab); // Set数据类型 无重复列表类型 // Set没有下标,不是按照下标存储,有序,不能使用下标循环遍历 // 插入速度和删除速度非常快 // 没有重复元素,任何元素存在唯一性,遍历查找速度也非常快,但是略低于键值对类型 var ab=new Set(); ab.add(1); ab.add(2); ab.add(3); ab.add(2); console.log(ab); ab.delete(2); console.log(ab.has(3));//判断这个元素是否在列表中存在 ab.clear();//清除所有数据 console.log(ab.size);//size就是长度,没有length var arr=[1,3,5,7,2,4,3,5,1,2,6,5,7,8,9,1,2,4,3,5,7,9]; arr=Array.from(new Set(arr)); console.log(arr); // Set使用场景 var manager={ list:[], add(elem){ if(this.list.indexOf(elem)>-1) return; this.list.push(elem); }, remove(elem){ var index=this.list.indexOf(elem); if(index<0) return; this.list.splice(index,1); }, update(){ for(var i=0;i<this.list.length;i++){ this.list[i].update(); } } } var manager={ list:new Set(), add(elem){ this.list.add(elem); }, remove(elem){ this.list.delete(elem); }, update(){ for(let value of this.list){ value.update(); } } } var times=new Date().getTime(); var ids=setInterval(animation,500); function animation(){ var obj={ name:"obj"+new Date().getTime(), update(){ console.log(this.name); } } manager.add(obj); if(new Date().getTime()-times>10000){ clearInterval(ids); manager.update(); } } var a=new Set([1,2,3,4,5]); a.forEach(function(value1,value2,a1){ console.log(value1,value2,a1); }) for(let value of a){ console.log(value); } // hashMap 键值对的数据类型 // map是一种由长度的键值对数据结构 // 具备数组的长度紧密型,又具备对象的键值对方法 // 它的获取,删除,查询,遍历速度很快 var map=new Map(); map.set("name","xietian"); map.set("age",30); console.log(map.size); map.delete("name");//删除键名 map.clear();//清除掉所有数据 console.log(map.get("age"))//获取某个键的值 console.log(map.has("age"));//判断某个键是否存在 console.log(map.values());//获取所有值的列表 console.log(map.keys());//获取所有键的列表 map.forEach(function(value,key,map){ console.log(value,key); }) for(let key of map.keys()){ console.log(key); } for(let value of map.values()){ console.log(value); } for(let arr of map.entries()){ console.log(arr[0],arr[1]); } map.set(15,15); map.set(true,true); var s=Symbol(); map.set(s,15); console.log(map.get(s)); for(let key of map.keys()){ console.log(key); } var obj={a:1,b:2}; var obj1={a:2,b:3}; map.set(obj,15); map.set(obj1,150); map.set(obj,obj1); console.log(map); // 任何类型都可以作为键使用 // WeakSet WeakMap 弱引用类型 // 弱引用,就是如果其中的强引用的类型地址设置为null,弱引用的关系会自动解除 var obj={a:1,b:2}; var obj1=obj; // obj=null; var s=new WeakSet(); s.add(obj); obj=null; console.log(s); // 弱引用的类型不可以遍历 for(var value of s){ console.log(value); } var dic=new WeakMap(); // WeakMap 存储的key必须是对象 var img=new Image(); var img1=new Image(); dic.set(img,img1); img=null; console.log(dic.get(img)); for(let value of dic.values()){ console.log(value); }
生成器函数
function *abc(a,b){ yield a; yield b; a++; yield a; b+=10; yield b; return a+b; } // 生成器对象 var a=abc(3,5); var obj=a.next();//{value:3,done:false}; // value就是yield返回的结果,done就是是否函数允许完成 console.log(obj); obj=a.next(); console.log(obj); obj=a.next(); console.log(obj); obj=a.next(); console.log(obj); obj=a.next(); console.log(obj); var obj=a.next(); console.log(obj.value) while(!obj.done){ obj=a.next(); console.log(obj.value); } let aaa=abc(10,20); for(let values of aaa){ console.log(values); }