es6新增语法介绍

本文详细介绍了从ES6到ES10的语法特性,包括let和const的使用,解构赋值,字符串和正则的扩展,箭头函数,Map和WeakMap,Set和WeakSet,以及Proxy和Reflect等。通过实例解析各项语法的用法和注意事项,帮助开发者深入理解ES6及后续版本的新特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ES6-ES10语法
ES5严格模式
用来消除语法中不合理,不严谨之处,让代码运行更安全,提高编译效率
限定内容
1.必须用var声明变量
2.函数的顶层不再指向window,而是undefined
2.不能定义和eval同名的变量,也不能创建相同的函数
4.禁止使用delete删除
5.禁止使用arguments,calee,caller
6.禁止使用with语句
// "use  strict"
    with(location) {
        console.log(hash)
        console.log(href)
        console.log(pathname)
    }
7.禁止函数参数重名
8禁止对象属性重名
9.禁止使用八进制的关键字
10.不允许在非函数的代码块内
列如:
“use strict"
b=23
console.log(b)
Object方法
1.Object.freeze()冻结一个对象(只能查询)
2.Object.isFrozen()是否冻结对象
3.object.seal()密封一个对象(不能添加和删除)
4.object.isSeal()是否被密封
5.Object.preventExtensions()让一个对象不可被扩展(不能添加)
ES6语法
let const
let类似于var,用来定义变量,但是let没有变量提升,只在代码块内有效
1.没有变量提升 
2.代码块内,可以创建私有变量
if(true){
    let a=12
}
console.log(a)//报错
3.解决事件循环机制问题
for(let i=1; i<5;i++){
    setTimeout(function(){
        console.log(i)
    })
}
4.暂时性死区
只要在块级作用中声明let,他就会绑定在这个区域,不再受外界影响
let a=1
function fun(){
    //暂时性死区
    a=2
    let a
    console.log(a)//报错,只找函数下的a 不去找全局的
}
5不允许重复声明
if(true){
    var a=12
    let a=55
    console.log(a)//报错,不能重复声明
}
const命令
const声明常量,一旦声明,常量的值不能改变
1.const具有let的所有特点,没有变量提升,代码块内可以定义为私有变量,不能重复声明,存在暂时性死区
var a=12
const a=55
console.log(a)//报错,不能重复声明
2.一旦声明,值不能改变
   const pi = 3.14
    console.log(pi)
        // pi = 3.5
    var num = pi * 3
    console.log(pi)报错
    3.本质:如果是基本类型的值,保证的是值不能改变,如果哟是引用类型的值,保证对象的地址不能改变,
    const arr=[1,2,3]
    arr[0]=66
    console.log(arr)//[66,2,3]
    const arr={a:"zxc"}
    console.log(arr)//报错
    面试题:var let和const区别
    1.var有变量提升,let和const没有变量提升
    2.var在函数下是私有变量,let const在代码块呢是私有变量
    3var可以重复定义,let constby不可以重复定义
    4.var 没有暂时性死区,let const具有let的所有特点,没有变量提升,代码块内可以定义为私有变量,不能重复声明,存在暂时性死区
    5.const定义的基本类型值保证值不能改变,引用类型值保证地址不能改变
    声明方法
    var let const function class import
    解构赋值  let [a, b, c] = [1, 2, 3]
    console.log(a)
    console.log(b)
    console.log(c)
    用来快速取出变量,减少语法写作
    例如:
   
    数组结构赋值
    1.解构赋值可以为任何类型,只要结构相对应
    let[a,b,c]=[1,{name:"aa"},[22,33]]
    2.可以缺少变量和值,但是不能类型不对应 
    let[a,b,c]=[1,2]//c是undefined
    let[a,b,]=[1,2,3]//3没有赋给变量
    let[a,b,c]=[1,,3]//b是undefined
    let[a,b,c]={}//报错,数组结构对象
    let[a,b,c]=22//报错,数组解构基本类型值
    3.可以与拓展运算符连用
     let [a, b, c, ...d] = [1, 2, 3, 45, 6, 89]、、扩展运算符只能放置在最后一个变量
     4可以设置模式
         let [a, b, c = 22] = [1, 2, undefined]//替代undefined
  5.对象结构赋值
  var obj={name:"list",age:23}
  let {age,name}=obj
  console.log(age)
  console.log(name)
  给属性重新命名,但是输出原属性名称,则报错
var obj={name:"list",age:23}
  let {age:a,name:b}=obj
  console.log(a)
  console.log(b)
  console.log(age)
  console.log(name)
  其他类型:
  ES6引用对象
  字符串的扩展
  1.includes(字符串,位置)是否找到了匹配值,返回布尔
  2.startWidth()判断是否以某个字符串开头,返回布尔
  3.endWidth()判断是否以某个字符串结尾,返回布尔
  4.repeat()把一个字符串重复n次
  5.padstart(长度,字符串)头补全字符串
  6.padEnd(长度,字符串)尾补全字符串
  consoloe.log("138".padstart(11,"*"))
                摸版字符串
                    摸版字符串是为了让我们拼接字符串,或者读取变量更简单
                    语法
                        1.模板字符串要定义在反单引号里
                        2.调用变量写在${}表达式里
                        3.摸版字符串下支持转义字符,例如:/n
                    执行
                        var name ="李四"
                        `<h1>姓名:${name}</h1>`
                        做运算
                        `<h1>姓名:${3+4}</h1>`
                        做三元表达式
                        `<h1>${age==23? "yes":'no'}<h1>`
                        调用函数
                        `<h1>${name.replace('i','#')}<h1>`
                        执行js的语法
                        alert`123`
                        function fun(){
                            return "zxc"
                        }
                        console.log(`${fun()}`)
数字的扩展
number
1.二进制 用0b或0B开头
2.八进制 用0o或0O开头
3,isNaN()判断是否为数字
4.parseInt()转换成整数
5.parseFloat()转换成浮点数
6.isFinite()是否为一个有限值
7.isInteger()判断是否是整数
数学的扩展                 
属性和方法
1.trunc()去除一个数的小数部分
2.sign()判断一个数是正数,负数,零,正数返回1,负数返回-1,零返回0
3.cbrt()求立方根
4.imul()返回带符号整数的乘积,非数字返回0
5.hypot()返回所有参数的平方和的平方根
6.指数运算符 2**3 //2*2*2=8     
bigInt
js的数字类型存储长度有限,bigint存储长度无限制,所以计算时不用考虑数字的溢出问题,可以计算大数字加法,列如银行的钱数,但是只能存储整形数字
最大整数
定义
var num =23n
类型typeof 66n bigInt
判断10==10n// true
转化BigInt("23")//23
bigInt(true)//1
1n+2n=3,
2+3n//类型不同不能直接计算 
数据类型:number,string,boolean,null,undefined,bigInt,symbol,Object
数组下的扩展
扩展运算符
表示方式:...,用把数组遍历成一个序列
列如:var arr=[1,2,3,4,3,5]
[...arr]
属性和方法
1.from()将对象转换成数组
2.of()将多个参数转换成数组
3.find(函数)返回查找的值,没有返回undefined
4.findIndex(函数)返回查找的位置,没有返回-1
5.fill(值)把值填充整个数组
6.keys()遍历所有key值
7.values()遍历所有value值
8.enties()遍历所有键值对
9.includes()判断是否包含指定值,返回布尔类型
10.copyWithin(替换位置,提取开始位置,结束位置)将数组中的指定值进行交换,
数组的空位
当定义一个数组,数组下没有给赋值,则数组下表存储的是空位,空位不是unddfined和null
,他不能参与其他值转化参与运算,如果非要输出,会默认输出undefined,但是不同方式处理空位不一样,
1.for/in foreach every some都会跳出空位
2.map会让空位保留,但不参与运算
3.for of,string,join把空位视为undefined
正则
正则是用字母,数字,符号组成,用来验证或筛选字符串内容,列入可以做表单验证,
定义:
let re=new REGexp("正则表达式","修饰符")
let re=new REGexp(/a/g)es6语法
let re=/a/g //简写
修饰符
i不区分大小写
g 全局匹配
m 实现多行匹配
u 以Unicode编码执行正则表达式(es6)
y 用来匹配多个值 ,只匹配粘连模式
s 匹配任意单个字符串,包括括号和转义字符
属性和方法
test()
验证字符串是否满足正则匹配,返回布尔值
exec()验证字符串是否满足正则匹配,返回字符串,否则null
compole()重新编译正则表达式
global是否设置了g,返回布尔值
ignoreCase 是否设置了i,返回布尔值
multiline 是否设置了m,返回布尔值
sticky是否设置了y修饰符,返回布尔值(es6语法)
flags返回正则表达式的修饰内容(es6)
source(返回正则表达式)
贪婪匹配:正则表达式返回的最长匹配懒惰匹配:正则表达式返回的最短匹配
varstr="asd/path-123/path-456/path-789" var re1=/(.*)(V)path-\d+/ var re2=/(.*?)(V)path-\d+/
console.log(str.match(re1))//贪婪匹配 console.log(str.match(re2))//懒惰匹配
前行断言后行断言
(?:a)可以匹配a前后的值(?=a)可以匹配a前面的值(?!a)反向匹配a前面的值
ES6新增 后行断言
(?<=a)可以匹配a后面的值(?<!a)反向匹配a后面的值
函数
        函数
        es6函数可以定义默认值 
        function fun(x=0,y=0){
            return x+y
        }

        函数与扩展运算符连用 
        function fun(x,...arr){
            console.log(x) 
            console.log(arr)
        }
        //函数与解构赋值连用 
        function fun([x,y,z]){
            console.log(x,y,z)
        }
        fun([3,4,5])
        function fun1({name:a,age:b}{
            console.log(a) 
            console.log(b)
        }
        默认值的作用域:一日设苦了默认值,函数进行声明时,参数会形成一个单独的作用域等到初
始化结束时,这个作用域会消失,这种语法在默认值时,不会出现
        var x=1
        function fun(x,y=x){console.log(y) } 
        fun(2)
        function fun1(y=x){
            let x=2
            console.log(y)
        }
        fun1()
        函数下定义严格模式,不能使用es6语法 
        function fun(x=3){
        "use strict' 
        console.log(x)
        }

    属性和方法
        name获得函数的名称
        length获得没有默认值的参数个数

        例如 
        var foo=function goo(){
            console.log(foo.name) //goo 因为函数goo付给第三方变量foo
        }
        例如:
        function fun(x,y,z=1){}
        console.log(fun.length)//2有两个参数不带默认值
        function fun1(x,y=1,z){}
        console.log(fun1.length)//1 当遇见一个默认值,则后面的变量都忽略不计
    箭头函数
        箭头函数用来简化函数体,用来解决this关键字的指向
        //带参数和返回值的箭头函数 
        var fun=(a,b)=>a+b
        //带一个函数的简写方法 
        var fun=a=>a
        //无参数的函数 
        var fun=()=>5
        //多行函数体
        var fun=()=>{console.log(111)}
        //带默认值的箭头函数
        var fun=(a=0,b=1)=>a+b
        //带扩展运算符
        var fun=(a...b)=>a+b.join("")
        //带解构赋值
        var fun=([a,b])=>a+b
        注意事项
        1.箭头函数体内的this指向定义时所在对象,不是使用是所在的对象
        2.箭头函数不能当做构造器使用,不能new命令,否则会报错
        3.箭头函数里不可以使用argument,但是可以使用扩展运算符
        4.不可以使用yield命令,不能用作Grenerator函数
        例如:
        var name="window" 
        var obj={
            name:"obj",
            say:function(){console.log(this.name) 
            fun:()=>{console.log(this.name)
        }
        obj.say()//obj 
        var foo=obj.say 
        foo() //window 
        obj.fun()//window 
        var f=obj.fun f
        ()//window
        改变this指向
        function Father(name,sex){
            this.name=name 
            this.sex=sex
        }
        function Son(name,sex,age)
        // Father.call(this,name,sex)
        // Father.apply(this[name,sex]
        // Father bind(this,name,sex)()
        Son::Father(…[name,sex])//类似于apply 
        this.age=age
        this.say=function(){
            console.log(this.name,this.sex,this.age)
        }
        var s=new Son("小明","男",23) 
        s.say()
            


    函数式编程
        纯函数
        一个函数的反回结果只依赖于的他的参数,叫做纯函数
        普通函数:有副作用,函数会改变其他环境的变量 
        var a=1
        function fun(b){ return a+b }
        纯函数:只能函数内部,不受外界影响 
        function fun1(x,y) {return x+y}
        高阶函数
                在函数下接收一个函数作为参数,叫做高阶函数
        你学过的高阶函数有什么?
        settimeout,map,filter,forEacth
        你自己写过的高阶函数
        防抖函数和节流函数
        function debouce(fun,time)//高阶
            var ter=null
            if(ter){clearTimeout(ter) }
            else{
            ter=setTimeout(function(){//闭包
            fun()
            },time)
        }
        柯里化函数
        一个函数传入一部分参数,此时就会返回一个函数函数来接收剩余的参数
        function add(a,b,c){ 
         return function(b){
            return function(c){
            return a+b+c
            }
          }
        }

        console.log(add(1)(2)(3))
对象
创建对象属性的简写方式
var name="lisi"
var obj={name}
定义对象下的方法
var obj={
    say(){

    }
}
属性名表达式
var obj={name:"lisi"}
obj.name
obj["name"]
obj["na"+"me"]
属性和方法
1.Object.is()用来比较两个对象是否相等
2.Object.assign()用来赋值可枚举的属性
3.Object.setPrototype(孩子,父类)设置一个对象的父类
4.keys()遍历对象下的属性名
5.values()遍历对象下的属性值
6.entries()遍历对象下的键值对
7.Object.getOwnPropertyDescriptors()返回某个对象的属性的描述
对象遍历的区别
 //遍历自身和继承的可枚举属性(不包含symbol属性)
        // for (var v in s) {
        //     console.log(v)
        // }
  //遍历自身可枚举属性(不包含symbol属性)
        // for (var v of Object.keys(s)) {
        //     console.log(v)
        // }
 //遍历自身属性,包含不可枚举(不包含symbol属性)
        console.log(Object.getOwnPropertyNames(s))
//遍历自身所有symbol属性
console.log(Object.getOwnPropertySymobols(s))
//便利自身所有属性(包含不可枚举的和symbol属性)
console.log(Reflect.ownkeys(s))
symbol类型
js的对象属性名都是字符串类型,这样造成属性名冲突,symbol用来保证属性名是独一无二的,解决冲突问题
定义
  var s1 = Symbol("name")
    var s2 = Symbol("name")
    类型:
        // console.log(typeof s1)//symbol
    判断
      var s1 = Symbol("name")
    var s2 = Symbol("name")
      // console.log(s1 == s2)false
      转化为字符传
      var s1=symbol("name")
      s1.tostring()//
      定义对象下的属性
        var s1 = Symbol("name")
 var obj = {
        name: "lisi",
        name: "xiaoming",
    }
    方法1
    obj[s1] = "xiaohong",
    方法2
    var p={[s1]:"小红"}
        console.log(obj[s1.,  ])//xiaohong
     方法3:
     Object.definedProperty(obj,s1,{value:"aa"})   
     定义对象下的函数
     var s1=Symbol("say")
     var obj={[s1]:function(){//函数里的内容}}
     obj[s1]()调用
   属性和方法
   Object.getOwnPropertySymobols()遍历对象下的symbol属性
   Reflect.ownkeys()遍历对象下所有属性
   Symbol.for()查找是否有匹配值,有值返回,没有创建
   Symbol.keyfor()查找是否有匹配值,有值返回,没有返回undefined
   Symbol.haslntance()判断该对象是否为某个构造器的实例,
   Symbol.isConcatSpreadable()判断是否可以用数组拼接方法,返回布尔值
   Symbol.species()指向当前对象的构造函数,
   Symbol.match()用来返回查找的值
   Symbol.replace()替换值
   symbol.search()查找值的所在位置
   symbol.split()分隔值
   symbol的方法调用方式
    var s1 = Symbol("name")

    function foo() {
        [s1] = "asd"
    }
    var f = new foo()
    console.log(foo[Symbol.hasInstance](f))、、true
    //数组拼接
    /  var arr = ["a"]
   // var arr1 = ["b"]
  //  console.log(arr[Symbol.isConcatSpreadable])//undefined
        // arr[Symbol.isConcatSpreadable] = false
        // console.log(arr.concat(arr1))//(2) [Array(1), 'b']
        // arr[Symbol.isConcatSpreadable] = true
        // console.log(arr.concat(arr1))//(2) ["a", 'b']
面向对象的class定义
在js里定义对象和后台语言不太相同,这样给程序学习时造成很大的困惑,所以es6提出用class声明对象,让语法更接近于后台语言,但是class只是一个语法糖,实际面向对象的思想还是和以前一样,
    class Emp {
            constructor(name, age) {
                this.name = name
                this.age = age
            }
        }
        var e = new Emp("si", 19)
  注意:
  1.class关键字只是一个语法,底层结构和es5一样

  2.class的实例上调用都是原型上的方法
  e.constructor==Emp.setPrototype.constructor//true
  3.在class声明体内都是严格模式
  在函数下定义num=12报错。没有声明,
  4.class声明的对象必须用new调用,否则会报错
  Emp()没有用new声明,会报错
  5.class声明的对象没有变量提升
  6.class声明的对象可以用函数表达式的形式
     var person = class pen {
            constructor(name) {
                this.name = name
            }
        }
        var b = new person("lisi")
        console.log(b)
私有变量和私有函数
在es6下没有提供私有的关键字,但是我们可以通过改变变量和函数名来模拟实现
    class obj {

            _x//私有变量
            constructor(x) {

                _x = x
            }
        }
        var a = new obj(33)
        console.log(a.x)、、报错,找不到变量
     私有函数
     class obj{
        foo(){
            _goo.call(this)
        }
     }   
     function _goo(){
        console.log(222222)
     }
     p._goo()//报错
     es6下的私有函数
       var s=Symbol("goo")
        class point{
           
            [s](){
                console.log(22222)
            }
        }
        var p=new point()
        p.goo()报错

        class Emp{
            constructor(){
                this.printname=(name="aa")=>this.info(`hello ${name}`)
            }
constructor(){
   
    this.printname=this.printname.bind(this)
}
            // printname(name="aa"){
               
            //     this.info(`hello ${name}`)
            // }
            info(n){
                
                console.log(n)
            }
        }
        var e=new Emp()
        var {printname}= e
        console.log(printname())

class下的geter和seter
      class obj {
            constructor(name) {
                this.name = name
            }
            get names() {
                return "触发get函数"
            }
            set names(name) {
                console.log("触发set方法")
                this.name = name
            }
        }
        var a = new obj("lisi")
        console.log(a.name)
        a.names = "张三"
        console.log(a.name)
   static静态关键字
   static修饰是静态方法和静态变量,当修饰方法时,方法不会被实例继承,方法和属性可以直接通过类名调用     
       class emp {
            say() {
                console.log(1111)
            }
            static info() {
                console.log(2222)
            }
        }
        console.log(emp.info())
        var a = new emp()
        console.log(a.info())//报错,实例继承不到
        静态的思想,类似于es5下这样定义:
        emp.info=function(){}//所有实例回访不到
    静态变量

     class emp {
            static name = "lisi"
            constructor() {
                console.log(emp.name)//lisi
                console.log(this.name)//undefined
            }
        }
        console.log(emp.name)//lisi
        var a = new emp()
        console, log(a.name)//报错

   new.target属性:判断对象是否通过new执行构造器,如果不是则返回undefined
      function Emp(name) {
            this.name = name
                // console.log(new.target)
            if (typeof new.target == "undefined") {
                throw new Error("必须用new关键字创建对象");
            } else {
                this.name = name
            }

        }
        Emp() //没有new对象
继承 extends
子类继承父类,可以拿到父类下的属性和方法,减少代码写作
 class Father {
            constructor() {
                this.name = "asd"
            }
        }
        class son extends Father {

        }
        var a = new son()
        console.log(a.name)//asd
super关键字:
super会有两种,一种当关键字用,一种当函数用
注意:当孩子创建自己的构造器,不写super会报错
当成函数来用表示调用父类构造器superclass Father {
            constructor(name) {
                this.name = name
            }
        }
        class son extends Father {
            constructor(name, age) {
                super(name)//调用父类构造器 ,当做方法使用
                this.age = age

            }
        }
        var a = new son("lisi", 23)写在变量赋值之前,

当成关键字使用,表示的是父类对象,通过对象可以调用父类的属性和方法  
  class Father {
            constructor(name) {
                this.name = name
            }
            foo() {
                console.log("父类的函数")
            }
        }
         class son extends Father {
        
            goo() {
                console.log(super.name)
                super.foo()
            }
        }
        var a = new son("lisi", 23)
    
        a.goo()//父类的函数
set和map
set:类似于数组,用来存储多个值,可以存储多种类型,但是所存储的值是唯一不可重复的,set是对对象体,用构造器赋值,接受一个数组类型
定义:
    var s = new Set([1, 2, 3, 4, 5, 5, 5, 1])
遍历:
for(var v of s){
    console.log(s)
}
属性和方法
size获取set长度
add()添加元素
deldete()删除元素
has()判断set是否有指定值,返回布尔
clear()清空set值
values()遍历所有value值
keys()遍历所有key值
entries()遍历所有键值对
foreach()遍历set所有值
注意:1.set集合没有索引值和key值,所以遍历出来的都是value,存储不保证有序
2.判断重复,不光值重复,类型也得相同
3.对于对象类型,保证的地址不能重复
   var s1 = new Set([1, 2, 3, 4])
   
    s1.add({})
    s1.add({})//两个空对象是不同地址,可以存
    var obj = {
        a: 1,
        b: 2
    }
    s1.add(obj)
    s1.add(obj)//两个都是obj对象,地址相同存一个
    面试题:
    1.数组去重
    var a = [1, 2, 3, 4, 5, 4, 3]
    // var s = new Set(a)
    // arr = [...s]
    // console.log(arr) //12345
    2.for in 不能遍历es6新数据结构
    3.交集,差集,并集
    交集 
    // var a = new Set([1, 2, 3])
    // var b = new Set([2, 3, 4])
    // var arr = [...a]
    // var t = arr.filter(function(index) {
    //     return b.has(index)
    // })
    // console.log(t)
    // var x = new Set([...a].filter(index => b.has(index)))
    //差集 
    // var arr1 = [...a]
    // var t1 = arr1.filter(function(index) {
    //     return !b.has(index)
    // })
    // var arr2 = [...b]
    // var t2 = arr2.filter(function(index) {
    //     return !a.has(index)
    // })
    // var x = [...t2, ...t2]
    // console.log(x)
    // var x = new Set([...a].filter(index => !b.has(index)))
    //var y = new Set([...b].filter(index => !a.has(index)))
    //并集
    // var s = new Set([...a, ...b])
    weakSet集合
    weakSet与set类型,保证值不能重复,但是weakset只能存储对象类型,weakset对对象都是弱引用,垃圾回收不用考虑weakSet对对象的引用
    定义:
    var ws=new weakSet([[1,2],[3,4]])
    只能存储引用类型
    ws.add(4)//报错,
    ws.add({})//可以
    对象都是弱引用
    var obj={a:1,b:2}
    ws.add(obj)
    obj=null
    console.log(ws)//weakset里的对象没有被清空
属性和方法
    add()添加元素
deldete()删除元素
has()判断set是否有指定值,返回布尔
clear()清空set值
map:
map结构类似于Object对象,用键值对存储,是hash结构,但是对象类型的属性只能存储字符串和symbol,map的key值可以为任何类型
定义:   var map = new Map([
            ["name", "lisi"],
            [1, true],
            [{
                s: 2
            }, 55]
        ])
        属性和方法:
        get(key)获取map的值
        set(key,value)获取或修改map值
        size()获取map长度
        deldete(key)删除map的值
        clear()清楚map
        keys()遍历所有key值
        values()遍历所有value值
        entries()遍历所有键值对
        foreach()遍历map所有值
        has()判断map是否有指定值,返回布尔
        注意:
        1.map的key和value都可以为任何类型
        2.map的key值不能重复,重复则为修改
        3.当key存储的基本类型保证值保证值不能重复,当为引用类型时地址不能重复
        key相同则修改
             // var map = new Map([
        //     ["name", "lisi"],
        //     [1, true],
        //     [{
        //         s: 2
        //     }, 55]
        // ])
        // map.set("name", "张三")
        // console.log(map)
        key唯一,所以可以存储任何类型
         // map.set(undefined, "s")
            // map.set(null, "b")
            // map.set(NaN, "C")
            // console.log(map)
            // console.log(map.size)
            // console.log(map.get(undefined))//s
            // console.log(map.get(null))//b
            // console.log(map.get(NaN))//c
         对于引用类型,必须保证使用的是同一个地址
                     // map.set(["a"], "b")
            // console.log(map)
            // console.log(map.get(["a"]))//undefined 值相同,地址不相同
        对于其他类型,只要值严格相同视为一样(===)
                   // map.set(+0, "a")
            // console.log(map.get(-0))//a 视为一个值
               map.set(true, "a")
               map.set("true", "b")
               console.log(map.get(true))//a

// //map转对象
        // var map = new Map([
        //     ["name", "lisi"],
        //     [1, true],
        //     ["a", 66]
        // ])
        // var obj = {}
        // for (var [k, v] of map) {
        //     obj[k] = v
        // }
        // console.log(obj)
        //对象转map
        var obj = {
            name: "lisi",
            true: 22,
            aa: 55
        }
        var map = new Map()
        for (var v in obj) {
            map.set(v, obj[v])
        }
        console.log(map)
weakMap 
weakMap类似于map,存储的是键值对,weakMap的key值存储的是对象类型,但是不包括null
weakMap的key如果引用了对象,不计入垃圾会使机制
定义

var wm=new weakMap([[{a:44},1],["xx"],true]])
key值只能存储对象类型
wm.set(1,"a")
wm.set(null,"a")//报错
weakMap的key如果引用了对象,不计入垃圾回收垃圾机制
var obj={a:1}
wm.set(obj,"a")
var obj=null
属性和方法:
 get(key)获取map的值
        set(key,value)获取或修改map值
        size()获取map长度
        deldete(key)删除map的值
      has()判断map是否有指定值,返回布尔值
      lterator(遍历器)
      在es5所有遍历函数只能遍历数组和集合,不能遍历新增的es6数据结构,所以es6下提供了遍历器的接口,方便我们可以通过,’遍历器访问任何数据类型
      作用
      1.为所有数据结构提供统一访问机制
      2.使数据结构的成员可以按照某种顺序排列
      3.通过for of命令直接迭代
      可以迭代的数据类型 :Array,Map,set,string,arguments,nodeList(节点对象)
      遍历器的原理:
      1.创建一个指针对象,指向当前数据结构的起始位置
      2.在第一次调用指针对象的next方法,可以将指针指向数据结构的第二个成员,
      3.不断的调用next方法会让指针依次寻找下一个成员,
      4.在next方法下用value存储每一次遍历的值,用done属性判断遍历是否结束,当值为true则结束
   function m(arr) {
        var index = 0
        return {
            next: function() {
                return index < arr.length ? {
                    value: arr[index++],
                    done: false
                } : {
                    value: undefined,
                    done: true
                }
            }
        }
    }
    var it = m(["a", "b", "c", "d"])
    console.log(it.next())
    console.log(it.next())
    console.log(it.next())
//迭代对象
    // // function myObjIterator(obj) {
    //     var arr = Object.keys(obj)//拿到obj的key值
    //     var index = 0;//定义数组的下标为0
    //     return {
    //         next: function() {//创建一个next函数
    //             return index < arr.length ? {//判断定义的值小于数组长度
    //                 value: obj[arr[index++]],
    //                 done: false
    //             } : {
    //                 value: undefined,
    //                 done: true
    //             };
    //         }
    //     }
    // }
    // var obj = myObjIterator({
    //     a: 1,
    //     b: 2,
    //     c: 3
    // });
    // console.log(obj.next());
    // console.log(obj.next());
    // console.log(obj.next());
</script>
    for和forEach区别
    1.for的参数为表达式,foreach的参数为函数体
    2.for的循环可以通过break结束,foreach即使写了return也不能停止,只是停止当前循环
    forin 和 for of
    1.for in遍历数组返回下标,for of遍历数组返回值
    2.for in 遍历对象返回key值,for of不能直接遍历对象,需要借助 Object.keys()
    3.for in不能遍历set和map, forof则可以
    4.for in遍历字符串返回下标,for of遍历字符串返回值
    proxy代理器
    proxy修改某些操作的默认行为的,类似于"元编程",对编程语言进行编程,proxy是对象的一个拦截
    层,对对象的方法进行拦截,处理更安全。
    定义\
    var obj=new Proxy(对象,限制)
    属性和方法:
    get(对象,属性,reflect)拦截对象的获取属性
    set(对象,属性,reflect)拦截对象的修改属性
    apply(目标对象,目标对象上下文,参数数组)拦截对象的apply方法
    constructor(对象,参数数组)拦截对象的new命令
    definedProperty(对象,属性,权限值)拦截对象的访问权限方法
    deleteProperty(对象,属性)拦截对象的delete关键字
    has(对象,属性)拦截对象的属性判断(in)
   grtOwnPropertyDescriptor(对象,属性)拦截对象的获得原型的方法
    isExtensible(对象)拦截对象的判断不可扩展方法
    ownkeys(对象)拦截对象的遍历属性方法(拦截全部)
    preventExtensions(对象)拦截对象的不可扩展方法 
    setPrototypeOf(对象)拦截对象的设置原型方法

列如:  var obj = new Proxy({
        name: "李四",
        age: 23
    }, {
        get: function(obj, key) {
            if (key == "age") {
                return 18//限制age不能访问
            } else {
                return obj[key]
            }
            // console.log("属性被查询了", obj, key)
        },
        set: function(obj, key, value) {
            if (key == "name") {
                return obj[key] //限制name不能修改
            } else {
                obj[key] = value
            }
            // console.log("属性被修改了", obj, key)
        }
    })
    obj.name = "张三"
    obj.age = 2
    console.log(obj.name)
    console.log(obj.age)

apply:
        function sum(a, b) {
        return a + b
    }
    var p = new Proxy(sum, {
        //obj目标对象
        apply: function(obj, obj1, args) {
            console.log("拦截器不让你改")
            return Reflect.apply(obj, ...arguments) * 2
        }
    })
    console.log(p(1, 2))

Reflect与proxy一样都操作对象的,Object对象下的方法都在Reflect下做了封装,用来消除
object下的方法的不合理的地方
 var obj = {
        name: ""
    }
    try{
        var a = Object.defineProperty(obj, "age", {})
    }
    catch(e){
        //自己处理错误
    }

    var b = Reflect.defineProperty(obj, "age", {})//判断返回的布尔类型值,可操作则为true
3.Reflect把Object下的命令换成了函数体
  var obj = {
        name: "lisi"
    }
    console.log("name" in obj) //命令判断
    console.log(Reflect.has(obj, "name"))//true//函数判断
 4. Reflect的方法与porxy方法一一对应  


   var obj = {
        name: "lisi",
        age: 18
    }
    var p = new Proxy(obj, {
        set: function(obj, key, value) {
            if (key == "name") {
                return Reflect.get(obj, key)
            } else {
                var a = Reflect.set(obj, key, value)
                if (a) {
                    // obj[key] = value
                    return Reflect.set(obj, key, value)
                }
            }
        }
    })
    p.name = "zhangsan"
    p.age = 24
    console.log(p.name, p.age)

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值