严格模式——let和const——箭头函数——解构赋值——字符串模板symbol——Set和Map——生成器函数

发布于:2022-07-28 ⋅ 阅读:(244) ⋅ 点赞:(0)

严格模式——let和const——箭头函数——解构赋值——字符串模板和symbol——Set和Map——生成器函数

??严格模式

严格模式下变量不能未通过定义直接调用赋值
不允许参数同名
禁止使用with
不要使用eval
不允许使用arguments.callee
不要evalarguments赋值
严格模式下函数及回调函数中this指向undefined
只读属性不能赋值
不能删除不可删除的属性
8进制 严格模式下不再使用


<script type="module">
   "use strict";
   //…………………………………………
</script>
<script type="module">
    // 自动严格模式
</script>
var div=document.querySelector("div");
//div.style.width="30px";
//div.style.height="30px";
//div.style.backgroundColor="red";
//禁止使用with
with(div.style){
    width="30px";
    height="30px";
    backgroundColor="red";
}
 var obj={
     option:{
         a:1,
         b:2
     }
 }

 with(obj.option){
     a=10;
     b=20;
     c=30;//如果对象中原属性存在,则修改属性的值,否则就会重新定义一个全局变量
 }
 console.log(obj,c)
不允许使用
arguments.callee
arguments.callee.caller
 console.log(this)//Window 
 function fn(){
     // 严格模式下函数及回调函数中this指向undefined
     console.log(this);//undefined
 }
 fn();
var a=3;
function fn(a){
    console.log(a+window.a);//8
}

fn(5);

*eval 反射 将字符串反射为表达式(因为是过于强大)ヾ(≧▽≦)o

// 不要使用eval
//eval 反射  将字符串反射为表达式
console.log(eval("3+4"));//7
var a=3;
console.log(eval("a+5"));//8


var o1={},o2={},o3={};

for(var i=1;i<4;i++){
    eval("o"+i).a=10;
}
console.log(o1,o2,o3)//{a: 10} {a: 10} {a: 10}

??let和const

?定义变量
let a=1;
?定义常量
const b=3;
个人解释;
var就像一个全局变量

let{} 限制作用域范围,并且再同一个作用域中不能重复使用let定义相同的变量名
const 常量 就是定义后不能改变的值
一般来说常量必须大写,而且以_区分单词

var a=3;
{
    a=4;
}
console.log(a);//4
let a=3;
{
    a=5;
}
console.log(a)//8

?块语句中用let定义的变量都是块作用域内的变量,块外不可调用?

let a=3;
{
   let a=5;//块语句中用let定义的变量都是块作用域内的变量,块外不可调用
}
console.log(a);//3
for(var i=0;i<10;i++){
}
console.log(i)//10for(let i=0;i<10;i++){
 
}
console.log(i)//报错
const obj={a:1,b:2};
obj={a:3,b:3};//为了防止引用类型更改其引用地址
obj.a=10;//可以修改其值,但是不能修改其引用地址
obj=null;
?建议不要这样写

箭头函数

?箭头函数实际上就是定义一个匿名函数
?如果箭头函数中参数仅有一个,可以省略()
?如果箭头函数中没有参数,或者一个以上的参数时,必须使用()
?如果函数内只有一条语句,可以省略{}
?同时相当于在最后一条语句中增加return 返回这个表达式结果
⚫箭头语句作用是处理this指向的问题
?this的指向具体点击这里this指向大全

var fn=(a,b)=>{
	return a+b;
}
等价于
var fn=function(a,b){
	return a+b;
}

// 如果箭头函数中参数仅有一个,可以省略()
// 如果箭头函数中没有参数,或者一个以上的参数时,必须使用()
var fn=(a)=>{
     console.log(a);//3
 }
var fn=a=>{
     console.log(a);//3
 }

fn(3);
var fn=(a,b)=>{
    return a+b;
}
?如果函数内只有一条语句,可以省略{}
?同时相当于在最后一条语句中增加return 返回这个表达式结果
var fn=(a,b)=>a+b;
var obj={
    c:this.d,当前对象外的this指向
    a(){
        console.log(this);obj
    },
    b:()=>{
        console.log(this);//指向当前箭头函数外this指向,和c属性赋值的this.d指向this相同
    }
}
obj.a();
obj.b();
"use strict";
var obj={
    a(){
        console.log(this);//obj
        // function fn(){
        //     console.log(this);//所有的函数直接调用,this都指向window,严格模式时指向undefined
        // }
        // fn();

        var fn=()=>{
            console.log(this);//this指向箭头函数外的上下文环境的this,obj
        }
        fn();{a: ƒ}
    }
}
obj.a();
var obj={
    ab:10,
    a(){
        console.log(this);//obj
        //这里的this就是obj
        //将obj赋值给document.o属性
        document.o=this;
        document.addEventListener("click",this.clickHandler);
    },
    clickHandler(e){
    	//谁侦听this就是谁
        console.log(this)//document
        //因为赋值给了引用地址,所以下面两条语句一样
        console.log(this.o.ab);//10
        console.log(obj.ab);//10
    }
};
obj.a()

?传统的这个事件函数this指向侦听元素

document.addEventListener('click',function(){
	console.log(this);//#doucument
})

?箭头函数this往外一翻,和函数外面调用this等价

document.addEventListener("click",e=>{
    console.log(this);//obj
})
var obj={
    ab:10,
    a(){
        this.handler=e=>this.b(e);
        document.addEventListener("click",this.handler);
    },
    b(e){
        e.currentTarget.removeEventListener("click",this.handler);
        console.log(this.ab);  
    }
}
var o=obj;
obj={};
o.a();


解构赋值

?数组解构
按位解构
ES5中参数时不允许有默认值的
ES6 可以设置参数的默认值

var arr=[1,2,3];
var [a,b,c]=arr;
console.log(a,b,c);//1 2 3
var obj={a:1,b:3,c:4};
var {a,b,c}=obj;
console.log(a,b,c);//1 3 4

变量的交换

var a=3;
var b=4;
[a,b]=[b,a];
console.log(a,b)//4 3
3 不进行赋值
var [a,b]=[1,2,3];
console.log(a,b);//1 2
c 是undefined
var [a,b,c]=[1,2];
console.log(a,b,c);//1 2 undefined
如果数组解构没有赋值给c,c默认值为3
var [a,b,c=3]=[1,2];
console.log(a,b,c);//1 2 3

?对象的解构
变量与key对应解构,变量名必须与key值相同
对象解构与顺序无关
当对象做深度解构时,属性名相同的,在解构时需要起别名

var {a,b,c}={b:10,a:3,c:6};
console.log(a,b,c)//3 10 6
function fn(a,b=2,c){
	console.log(a,b,c);//3 2 5
}

fn(3,undefined,5);
function fn({a,b,c}){
    console.log(a,c,b);//10 20 undefined
}

fn({a:10,c:20});
var {a,b,c=3}={a:1,b:2};
console.log(a,b,c);//1 2 3
var {a,b:{a:a1}}={a:1,b:{a:2}};
console.log(a,a1);//1 2

? 凡是有实例的对象方法都不要做解构
?有的对象中使用了this,这种对象不能进行解构,如果解构后,this的指向就会发生改变

var str="abvcde";
var {length:len}=str;
console.log(len);//6

这两就属于可以解构

var {random,max}=Math;
console.log(random()*10)
console.log(max(10,20))

解构练习

var {a,b:{a:a1=3}={a:10}}={a:1,b:{a:2}}
a=1  a1=2
var {a,b:{a:a1=3}={a:10}}={a:1}
a=1  a1=10
var {a,b:{a:a1=3}={a:10}}={a:1,b:{}};
a=1 a1=3
function fn({a,b:{a:a1}={a:10}}={a:20,b:{a:30}}){
    console.log(a,a1);
}
fn();//20,30
fn({});//undefined 10
fn({a:1});//1 10
fn({a:1,b:{}});//1 undefined
fn({a:1,b:{a:50}});//1 50

var obj= {a:10,b:{b:{a:20}}};
a=10  a1=20;
var obj={a:10,b:{b:{}}};
a=10 a1=100
var obj={b:{}}
a=20 a1=0;

var obj={};
a=20  a1=-1

var {a=20,b:{b:{a:a1=100}={a:0}}={b:{a:-1}}}=obj;
console.log(a,a1)

字符串模板和symbol

?“``”插值
symbol 不重复,唯一类型
Symbol不做运算
对象中key可以使用字符型和Symbol型
使用Symbol作为key可以防止key因为重名而覆盖

var div=document.querySelector("div");

var list=[
    {site:"腾讯",href:"http://www.tencent.com"},
    {site:"百度",href:"http://www.baidu.com"},
    {site:"京东",href:"http://www.jd.com"},
    {site:"淘宝",href:"http://www.taobao.com"},
    {site:"网易",href:"http://www.163.com"},
    {site:"小米",href:"http://www.mi.com"}
]

div.innerHTML=`
    <ul>
        ${list.reduce((v,t)=>`${v}<li><a href='${t.href}'>${t.site}</a></li>`,"")}
    </ul>
`
div.innerHTML=`
   <ul>
       ${(function(){
           var str="";
           for(let i=0;i<list.length;i++){
               str+=`<li><a href='${list[i].href}'>${list[i].site}</a></li>`
           }
           return str;
       })()}
   </ul>
 `
var a=Symbol();
var b=Symbol();
var obj={
	[a]:10,
	[b]:20
}
console.log(obj[a]);

能使用for in key是字符串类型的属性,而不是Symbol类型

for(var key in obj){
	console.log(key)
}

去除魔术字符串

const LEFT=Symbol(),TOP=Symbol(),RIGHT=Symbol(),BOTTOM=Symbol();

var list = [LEFT,TOP,RIGHT,BOTTOM];

var state;
init();

function init() {
    document.addEventListener("keydown", keyHandler);
    document.addEventListener("keyup", keyHandler);
    setInterval(animation, 16);
}

function keyHandler(e) {
    if(e.type==="keyup") return  state=undefined;
    state = list[e.keyCode - 37];
    state=TOP;
}

function animation() {
    if (!state) return;
    switch (state) {
        case LEFT:
            console.log("left")
            break;
        case TOP:
            console.log("top")
            break;
        case RIGHT:
            console.log("right")
            break;
        case BOTTOM:
            console.log("bottom")
            break;
    }
}

Set和Map

? Array 元素列表
元素没有指向某个名称,有下标,紧密结构,根据前一个可以找到后一个,有前后关系所以能够排序,添加删除元素速度比较慢,数组的元素可以重复,需要遍历查找

?Object 键值对
无序,松散结构,没有前后关系,插入速度快,删除速度快,查找速度快(以key存储)

?Set
没有索引,无序集合,没有前后关系,插入,删除速度快,不能排序,不能重复。集合有数量长度 size


?Map
var m=new Map([[“a”,1],[“b”,2]]);
var m=new Map(迭代器)

键值对 属性key 长度 结构 顺序
对象 string、Symbol 没有 松散结构 先数值 后字符key,不可枚举Symbol
Map 任意类型 有size 松散结构 无顺序(遍历按照添加的先后顺序)
var m=new Map([["a",1],["b",2]]);
console.log(m)
//Map(2) {'a' => 1, 'b' => 2}
// var m=new Map(迭代器)
var o={a:1,b:2,c:3};
console.dir(Object);//Object()
// 将对象转换为迭代器所需数组结构
var arr=Object.entries(o);
console.log(arr)//[Array(2), Array(2), Array(2)]
// 将o对象放入到map,转换为map
var m=new Map(Object.entries(o));
console.log(m);//Map(3) {'a' => 1, 'b' => 2, 'c' => 3}
// 将迭代器map转换为对象
var o1=Object.fromEntries(m);
console.log(o1)//{a: 1, b: 2, c: 3}
清空 根据key获取值 根据键删除值 判断是否有这个键值对 获取键值对的数量
m.clear() m.get(“a”) m.delete(‘true’); m.has(“true”) m.size
delete删除对象

遍历map:

var m=new Map();
m.set("a",1);
m.set(true,2);
m.set("true",0);
var o={a:1};
m.set(o,3);//用对象的引用地址作为键存储
var o1=o;
o={a:3};
m.forEach(function(value,key){
    console.log(key,value)
})
for(var [key,value] of m){
    console.log(key,value)
}
// m.keys() 获取map的key对应的迭代器
// m.values() 获取map的value对应的迭代器
// 只遍历所有key
for(var key of m.keys()){
	console.log(key);
}

for(var value of m.values()){
	console.log(value)
}


for(var [key,value] of m.entries()){
	console.log(key,value)
}

顺序点击器
在这里插入图片描述

var m=new Map();
var bns=document.querySelectorAll("button");
m.set(bns[0],bns[1]);
m.set(bns[1],bns[2]);
m.set(bns[2],bns[3]);
m.set(bns[3],bns[4]);


bns[0].addEventListener("click",clickHandler);

function clickHandler(e){
    console.log(this.textContent);
    this.removeEventListener("click",clickHandler);
    if(!m.has(this)) return;
    m.get(this).addEventListener("click",clickHandler);
}


生成器函数

阻塞式同步,预加载图片

    // 阻塞式同步
function *loadImage(){
    var arr=[];
    for(var i=78;i<83;i++){
        var img=new Image();
        img.src=`./img/img_${i}.jpeg`;
      yield img.onload=function(){
            arr.push(this);
            g.next();
        }
    }
    arr.forEach(item=>console.log(item.src));
}

var g=loadImage();
g.next();
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到