严格模式
<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);
}