ES2015前端基础知识集锦

前端 admin 3个月前 (08-24) 214次浏览 0个评论 扫描二维码

1、块变量let

for (var i=0;i<3;i++){
    for (var i=0;i<3;i++){

    }
}
// 该循环中的变量i是公用的,只会循环3次
for (let i=0;i<3;i++){
    for (let i=0;i<3;i++){

    }
}
// 该循环中的变量i是块级变量,第一层循环和第二层循环不互相影响 可以循环9次

2、使用闭包摆脱全局作用域的变量

var elements = [{},{},{}];
for (var i=0; i < elements.length; i++){
    elements[i].onclick = (function(i){
        return function(){
            console.log(i)
        }
    })(i);
}
elements[0].onclick()
// 使用let达到闭包的效果
for (var i=0; i < elements.length; i++){
    elements[i].onclick =function(){
            console.log(i)
        }
}
elements[0].onclick()

3、数组解构Destructing

从数组中快速获取元素的方式

// 以前的做法
const arr = [100,200,300]
const a = arr[0]
const b = arr[1]
const c = arr[2]
console.log(a, b, c)
// 解构
const [a, b, c] = arr;
const [, , c] = arr;
const [, ...ret] = arr;
console.log(ret) // [200, 300]
const [q] = arr;  // 100
const [x, y, z, t] = arr; // 100, 200, 300, undefined
const [x, y, z, t = 400] = arr; // 100, 200, 300, 400

4、对象解构

const obj = {name: 'zhangsan', age: 18}
const {name} = obj
console.log(name) // zhangsan
const {username} = obj
console.log(username) // undefined
// 命名冲突的解决办法
const name = 'tom';
const {name: objName, username = 'test'} = obj
console.log(objName, username) // zhangsan test
// 解构console.log
const {log} = console
log('a')

5、模板字符串

const name = 'tom'
const test = `hello, ${name}`
// 高级用法 标签函数
const a = 'zhansgan'
const b = 'lisi'
/**
function myTagFunc(strings){
    console.log(strings) // ['name: ', ' and name:', ' 111']
}
*/
function myTagFunc(strings, a, b){
    console.log(strings, a, b) // ['name: ', ' and name:', ' 111']  zhangsan lisi
}
const result = myTagFunc`name: ${a} and name: ${b} 111`  

字符串扩展

// includes()
// startsWith()
// endsWith()
const a = 'Error: 1234';
console.log(a.startsWith('Error')); // true
console.log(a.endsWith('1234'));  // true
console.log(a.includes('Error')); // true

6、剩余参数

function a(b, ...args){
    console.log(args); //  [2, 3, 4]
}
a(1, 2, 3, 4)

7、展开数组Spread

const arr = [100, 200, 300];
console.log.apply(console, arr); // 100 200 300
// es2015
console.log(...arr);  // 100 200 300

8、箭头函数

const inc = n => n + 1
console.log(inc(100)) // 101
const add = (x, y) =>  {
    console.log(x + y );
    return x + y;
}
// 最大作用,极大的简化了回调函数
const b = [1,2,3,4,5,6,7]
b.filter(x => x % 2)
// 箭头函数不会改变this的指向
const person = {
    name: 'tom',
    //sayHi: function() {
        //console.log(`hi, my name is ${this.name}`) // hi, my name is tom  这里的name后来被改变了内容
    //},
    sayHiAsync: function(){
        /**
        const _this = this;
        setTimeOut(function() => {
            console.log(`hi, my name is ${_this.name}`)
        }, 1000) // hi, my name is undefined 使用const _this = this;后何以使用this
        */
        setTimeOut(() => {
            console.log(`hi, my name is ${_this.name}`) // hi, my name is tom
        }, 1000)

    },
    sayHi: () => {
        console.log(`hi, my name is ${this.name}`) // hi, my name is undefined
    }
}
person.sayHi()

9、对象字面量的增强

const bar = '456';
    const obj = {
      name: '123',
      bar,
      method1(){
        console.log('111111');
        console.log(this); // 指向当前变量
      },
      [Math.random()]: '11',  // 计算属性名
      ['234']: '11',  //  计算属性名可以是任意变量
      [bar]: '11',  //  计算属性名可以是任意变量 => '234': '11'
    };
    console.log(obj); // {name: '123', bar: '456', method1: [Function: method1]}
    obj.method1(); // 调用method1

对象扩展方法

const source1 = {
    a: 123,
    b: 123
}
const source2 = {
    b: 789,
    d: 789
}
const target = {
    a: 456,
    c: 456
}
// 合并target 和 source1
const result = Object.assign(target, source1, source2); // 用后边对象的内容覆盖前边的对象
console.log(target); // {a: 123, c: 456,  b: 789, d:789}
console.log(target === result); // true
// 函数内对象不影响函数外对象
function func(obj){
    const funcObj = Object.assign({}, obj);
    funcObj.name = 'lisi'
    console.log(funcObj); // {name: lisi} 类似于深拷贝
}
const obj = {name: 'zhangsan'}
func(obj);  // {name: lisi}
console.log(obj); // {name: zhangsan}  

Object.is(+0, -0) // false
Object.is(NaN, NaN)

10、代理对象Proxy

const person = {
      name: 'zhangsan',
      age: 20
    };
const personProxy = new Proxy(person, {
      get(target, property){
        console.log(target, property);
        return property in target ? target[property] : undefined;
      },
      set(target, property, value){
        target[property] = value;
        return true; // 写入成功
        // console.log(target, property, value);
      },
      deleteProperty(target, property): boolean {
        delete target[property];
        return true;
      }
});
const list = [];
const listProxy = new Proxy(list, {
      set(target, property, value){
        console.log('set', property, value); // set 0 100
        target[property] = value;
        return true;
      }
});
listProxy.push(100);
// Proxy和Object.defineProperty()的区别
// defineProperty智能监控到对象的属性的读写
// Proxy能监控到更多对象操作
// deleteProperty监控删除属性的事件
// Proxy是以非侵入的方式见惯了对象的读写

11、统一的对象操作API Reflect

// Reflect 是一个静态类 不能使用new Reflect()
const obj = {
      name: 'zce',
      age: 18
    };
console.log('name' in obj);  // true
console.log(delete obj.age);  // true
console.log(Object.keys(obj)); // [ 'name']
console.log(Reflect.has(obj, 'name'));
console.log(Reflect.deleteProperty(obj, 'age')); 
console.log(Reflect.ownKeys(obj)); // ['name']

12、唯一类型Symbol

// 使用Symbol创建对象的私有成员
const name = Symbol();
const person = {
    [name]: 'zce',
    say(){
        console.log(this[name]);
    }
}
// 该name只能在person内访问,在person外无法访问
// Symbol最主要的作用就是为对象添加独一无二的属性名
console.log(Symbol() === Symbol()); // false
console.log(Symbol('bar') === Symbol('bar')); // false
console.log(Symbol.for('bar') === Symbol.for('bar')); // true
console.log(Symbol.for('true') === Symbol.for(true)); // true 自动降对象转为字符串 需要注意
console.log(Symbol.iterator); //  Symbol(Symbol.iterator)
console.log(Symbol.hasInstance);
console.log({}.toString());  // [object Object]
console.log({[Symbol.toStringTag]: 'XObject'}.toString()) // [object XObject]

13、for循环

// for遍历普通数组
// for...in 适合遍历键值对
// 对象的foreach
// es2015引入for...of统一遍历方式
// for...of遍历原理
const set = new Set([100,200,300]);
const iterator = set[Symbol.iterator]();
console.log(iterator.next()); // {value: 100, done: false}
console.log(iterator.next()); // {value: 200, done: false}
console.log(iterator.next()); // {value: 300, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
// 自定义实现对象的iterator迭代器
const a = {
      store: [100, 200, 300],
      [Symbol.iterator]: () => {
        let index = 0;
        const self = this;
        return {
          next: () => {
            const result = {
              value: a.store[index],
              done: index >= a.store.length
            };
            index ++;
            return result;
          }
        };
      },
};

for (const item of a){
    console.log('循环体', item);
}

14、迭代器的意义

// 对外提供统一接口
const todos = {
      life: ['吃饭', '睡觉', '打豆豆'],
      learn: ['语文', '数学', '英语'],
      work: ['喝茶'],
      each: (callback) => {
        const all = [].concat(todos.learn, todos.learn, todos.work);
        for (const item of all){
          callback(item);
        }
      },
      [Symbol.iterator]: (callback) => {
        const all = [...todos.life, ...todos.learn, ...todos.work];
        let index = 0;
        return {
          next: () => {
            return {
              value: all[index],
              done: index ++ >= all.length
            };
          }
        };
      }
    };

    for (const item of todos){
      console.log(item);  // 遍历数组中所有的内容
    }

15、生成器Generator

// 为了在复杂的异步代码中,减少异步函数嵌套的问题,提供更好的异步编程解决方案
// 定义生成器函数
function * a() {
  console.log('zce');
  return 100;
}
const result = a();
console.log(result); // Object [Generator]{} 生成器对象
console.log(result.next()); // 执行 zce {value: 100, done: true}
function * foo() {
  console.log('1111');
  yield 100;
  console.log('2222');
  yield 200;
  console.log('3333');
  yield 300;
}
const generator = foo();
console.log(generator.next()); // 1111  {value: 100, done: false}
console.log(generator.next()); // 2222  {value: 200, done: false}
console.log(generator.next()); // 3333  {value: 300, done: false}

生成器应用

// 案例一:发号器
function * createIdMaker(){
  let id = 1;
  while(true){
        yield id++; // yield过后方法被暂停 不用担心死循环问题
  }
}
const idMaker = createIdMaker();
console.log(idMaker.next().value);  // 1
console.log(idMaker.next().value);  // 2
console.log(idMaker.next().value);  // 3
console.log(idMaker.next().value);  // 4
// 案例二:使用Generator 实现 iterator 方法
const todos = {
      life: ['吃饭', '睡觉', '打豆豆'],
      learn: ['语文', '数学', '英语'],
      work: ['喝茶'],
      [Symbol.iterator]: function * a(callback) {
        const all = [...todos.life, ...todos.learn, ...todos.work];
        for (const item of all){
          yield item;
        }
      }
};

for (const item of todos){
  console.log(item);
}

16、ES2017特性

const obj = {
  foo: 'value1',
  bar: 'value2'
}
console.log(new Map(Object.entries(obj))); // Map('foo' => 'value1', 'bar' => 'value2')
// 对象拷贝 包含对象的方法
const p1 = {
      firstName: 'Lei',
      lastName: 'Wang',
      get fullName(){
        return this.firstName + ' ' + this.lastName;
      }
};

// const p2 = Object.assign({}, p1);
// p2.firstName = 'zce';
// console.log(p2.fullName);  // Lei Wang  Object.assign会把fullName当作普通属性进行复制

const descriptiors = Object.getOwnPropertyDescriptors(p1); // 获取对象的所有描述信息
const p2 = Object.defineProperties({}, descriptiors);
p2.firstName = 'zce';
console.log(p2.fullName); // zce Wang

// 字符串补齐
const name = 'zhangsan';
const age = '18';
console.log(name.padEnd(10, '-'));  // zhangsan--
console.log(age.padStart(5, '0'));  // 00018

codeobj , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:ES2015前端基础知识集锦
喜欢 (0)
[a37free@163.com]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址