ECMAScript6+再整理学习

2021-06-23  本文已影响0人  squidbrother
Ecma国际

Ecma国际自2011年发布国际标准后,到2015年才正式发布新版本 ECMAscript6.0
整体推出都着重解决了哪些问题呢?

  1. 为什么出现let、const
    首先是作用域,ES6之前存在 全局作用域、函数作用域,但是并没有块级作用域
for(var i=0; i<aBtns.length; i++){
  aBtns[i].onclick = function(){
    console.log(i)
  }
}

上述代码,不管点击哪个按钮,其实返回的都是aBtns.length,而非预期的0,1,2,....
这是因为 var 声明的变量是全局的,绑定事件后,其索引i依然累加到aBtns.length了

解决方式:
可以将i做为属性,或者使用函数作用域包裹,如:

var aBtns = document.getElementsByTagName('button');
for(var i=0; i<aBtns.length; i++){
    (function(i){
        aBtns[i].onclick = function(){
            console.log(i)
        }
    })(i);
}

也可以使用新出现的let的块级作用域

for(let i=0; i<aBtns.length; i++){
  aBtns[i].onclick = function(){
    console.log(i)
  }
}
console.log(a==undefined); //true
var a = 1;

在不删除var的情况下,推出const、let;
严格的执行 变量'先声明后使用'的原则,否则报错

const num = 1;
num = 2; //报错 赋值无效

针对引用类型修改属性ok

const student = { name:'', age:0 }
student.name = '张三';
student.age = 18;
console.log(student); //{ name: "张三", age: 18 }

但是针对引用类型数据,直接修改内存地址指向,那么直接报错,因为前后对象内存地址不一样了
如:

const obj = { num:1 }
obj = { num:2 } //报错 赋值无效
  1. 数组结构与对象结构
    关于数组:
const data = [1,2,3]
let [a,b,c] = data;
console.log(a,b,c) // 1 2 3
const data = [1,2,3]
let [a,...b] = data;
console.log(a,b) // 1 [2,3]
const data = [1,2,3]
let [a,b,c,d=4] = data;
console.log(a,b,c,d) // 1 2 3 4

关于对象:

const obj = {name:'zhangsan'}
let {name: objName='default'} = obj;
const name = '123'
console.log(objName); //zhangsan

2-1. 数组与对象中使用展开运算符
优雅的罗列出数组的每一项

const arr = [1,2,3]
console.log(...arr);

在react中,由于底层针对引用数据类型的浅比较,所以不能修改原来的数据引用地址
因此,要返回新的数组或者对象,所以常使用这个展开运算符
如数组 :

const oldData = [1,2,3]
const newData = [ ...oldData, 4,5,6 ]
console.log(newData); //  [ 1, 2, 3, 4, 5, 6 ]

如对象(修改值) :

const obj1 = { name:'zhangsan', age:18 }
const obj2 = { ...obj1, age:20 };
console.log(obj2,obj1==obj2);  // { name: "zhangsan", age: 20 }   false

2-2. 对象的修改,亦可使用Object.assign ,但是第一个参数是谁,结果就是谁的;如果是个空对象,则返回是新对象

const obj1 = { name:'zhangsan', age:18 }
const obj2 = Object.assign(obj1,{name:'lisi'})
console.log(obj2,obj1==obj2); // { name: "lisi", age: 18 }  true

返回一个新对象

const obj1 = { name:'zhangsan', age:18 }
const obj2 = Object.assign({},obj1,{name:'lisi'})
console.log(obj2,obj1==obj2);  // { name: "lisi", age: 18 } false
  1. 函数参数默认值
    没有默认参数的情况下,
function myFn(data){
    data = typeof data === 'undefined' ? 100: data;
    console.log(data)
}

有默认参数的情况下

function myFn(data=100){
    console.log(data)
}
  1. 函数中,不定参的剩余值
function myFn(data,...data2){
    console.log(data); //100
    console.log(data2); // ['aaaa',{name:'zhangsan'}]
}
myFn(100,'aaaa',{name:'zhangsan'})
  1. 箭头函数
let addOneFn = num => num+1;
console.log(addOneFn(1)) // 2
const obj = {
    name:'zhangsan',
    sayHi:()=>{
        console.log(this); // window
    },
    sayHiAsync: function(){
        console.log(this) // obj
        setTimeout(()=>{
            console.log(this.name) // zhangsan
            console.log(this) // obj
        },300)
    }
};
obj.sayHi();
obj.sayHiAsync(); 
  1. Obejct.is 能比较出NaN是否等于NaN的特殊比较函数
Object.is(NaN,NaN); //true
Object.is(+0,-0); //false
  1. Proxy 监测对象属性变化
    vue3底层中收集依赖的方式,监测数据变化
const data = { name:'zhangsan', age:18 };
const oP = new Proxy(data,{
  set(obj,attr,val){
    obj[attr] = val;
  },
  get(obj,attr){
    return obj[attr];
  }
});

oP.name = 'lisi'
console.log(oP.name); //lisi
  1. Reflect同proxy类似,同样操作对象相关属性
// 老写法
'name' in myObj// true
// 新写法
Reflect.has(myObj, 'name') // true
Reflect.get(myObj, 'name');
Object.keys(myObj);
Reflect.ownKeys(myObj)
// 老写法
delete myObj.name;
//新写法
Reflect.deleteProperty(myObj, 'name');
  1. symbol
const objName = Symbol();
const obj = {
    [objName]:'aaaa',
    sayName:function(){
        console.log(this[objName])
    }
};
obj.sayName();

获取Symbol属性名

const obj = {};
let a = Symbol('a');
let b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
const objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
  1. generator解决异步请求嵌套的问题
function * fn(){ ... }
function * say(){
    yield 'a';
    yield 'b';
    yield 'c';
}
const generator1 = say();
let result1 = generator1.next();
let result2 = generator1.next();
let result3 = generator1.next();
let result4 = generator1.next();
console.log(result1,result1.value,result1.done); // {value: "a", done: false} "a" false
console.log(result2.value,result2.done); //b false
console.log(result3.value,result3.done); //c false 
console.log(result4.value,result4.done); //undefined true
  1. 数组方法indexOf不能查找NaN
    新增数组方法incloudes
['a',1,2,NaN].includes(NaN); //true
  1. 类的继承与静态方法
class Person {
    constructor(name,age) {
        this.name = name
        this.age = age
    }
    say(){
        console.log(`我叫${this.name},我${this.age}岁`);
    }
    static createOne(name,age){
        return new Person(name,age);
    }
}

class Student extends Person {
    constructor(name,age,school) {
        super(name,age);
        this.school = school;
    }
    myschool(){
        console.log(`${this.name}上${this.school}`);
    }
    static createOne(name,age,school){
        return new Student(name,age,school);
    }
}

const p1 = Person.createOne('张三',18); //new Person('张三',18);
p1.say();   

const s1 = Student.createOne('李四',30,'高中二年级'); //new Student('李四',30,'高中二年级');
s1.say()
s1.myschool();  

未完待续...

上一篇 下一篇

猜你喜欢

热点阅读