Javascript ES6重点学习总结

ES6

学习部分重要ES6知识点的总结。。长,可以先码后看

环境搭建

  • 在项目目录下新建目录src(承载es6语法)和dist(承载编译之后的es5语法)
  • 在项目中npm init -y初始化
  • 安装babel-cli babel-preset-es2015
  • 在根目录下新建.babelrc文件
{
  "presets":[
    "es2015"
  ],
  "plugins":[]
}
  • 在src中写es6语法后,运行babel src/index.js -o dist/index.js

新的声明方式

  • var 全局变量
  • let 局部变量
  • const 静态变量

变量的解构赋值

  • 数组的解构赋值
let [a,b,c] = [1,2,3];
let [a,[b,c],d] = [1,[2,3],4];

let [foo=true] = [];
console.log(foo) // true

let [a,b="World"] = ["Hello"]
console.log(a+b) // HelloWorld

let [a,b="World"] = ['Hello',undefined]
console.log(a+b) //HelloWorld

let [a,b="World"] = ['Hello',null]
console.log(a+b) // Hellonull
  • 对象的解构赋值
// 不用按次序,但是要名相同
let {foo,bar} = {bar:'World',foo:'Hello'}
console.log(foo+bar) //HelloWorld

// 如果解构前,已经定义了变量,需要在解构的语句外面加一个圆括号
let foo;
({foo}={foo:'Hello1'})
console.log(foo)
  • 字符串的解构
const [a,b,c,d,e]="Hello"
console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)

扩展运算符和rest运算符

  • 对象扩展运算符(…)
// 运用1:对于一个方法传入参数不确定
function f(...arg) {
  console.log(arg[0])
  console.log(arg[1])
  console.log(arg[2])
}
f(1,2) // 1,2,undefined

// 运用2:解决数组赋值只是堆栈引用问题
let arr1=['www','baidu','com'];
//let arr2=arr1;
let arr2=[...arr1];
console.log(arr2);
arr2.push('hh');
console.log(arr2); //["www", "baidu", "com", "hh"]
console.log(arr1); //["www", "baidu", "com"]
  • rest运算符
function f(first,...arg){
    console.log(arg.length);
}
f(0,1,2,3,4,5,6,7); //7

function f1(first,...arg){
    for(let val of arg){  // for of循环可以避免开拓内存空间,增加运行效率
        console.log(val);
    }
}

f1(0,1,2,3,4,5,6,7); // 1,2,3,4,5,6,7

字符串模版

let s1='hhh';
let blog = `非常高兴你能看到这篇文章,${s1}`;
document.write(blog);

//支持html标签
let s2='hhh';
let blog = `非常高兴你能看到这篇文章</b>,${s1}`;
document.write(blog);

//对运算的支持
let a=1;
let b=2;
let result=`${a+b}`;
document.write(result); //3

字符串查找

let s1='hh';
let blog = '非常高兴你能看到这篇文章,我是你的老hh';
document.write(blog.includes(s1));

//判断开头有没有 startsWith
//判断结尾有没有 endsWith

复制字符串

document.write('hhh|'.repeat(3));

ES6数字操作

  • 二进制和八进制
let er = 0b010101 //21
let ba = 0o666 //438
  • 数字判断和转换
// 数字验证
let a = 11/4;
console.log(Number.isFinite(a)) // true

//NaN验证 NaN是特殊的非数字
console.log(Number.isNaN(NaN)) //true

// 判断是否为整数
console.log(Number.isInteger(123.4)) //false

// 整数转换、浮点数转换
let a = '9.18'
console.log(Number.parseInt(a))  //9
console.log(Number.parseFloat(a)) //9.18

// 整数取值范围操作
let a = Math.pow(2,53)-1 // 最大的整数2^53-1

// 最大安全整数
console.log(Number.MAX_SAFE_INTEGER)

// 最小安全整数
console.log(Number.MIN_SAFE_INTEGER)

// 安全整数判断
let a = Math.pow(2,53)-1;
console.log(Number.isSafeInterger(a)) //false

ES6新增的数组知识

  • JSON数组格式转换
let  json = {
    '0': 0,
    '1': 'hh',
    '2': 'hello',
    length:3
}

//将json转化为数组
let arr = Array.from(json)

//将一堆文本或者变量转换成数组
let arr = Array.of(3,'4',5,6)
  • find()方法

在find方法中我们需要传入一个匿名函数,函数需要传入三个参数:
* value:表示当前查找的值。
* index:表示当前查找的数组索引。
* arr:表示当前数组。

在函数中如果找到符合条件的数组元素就进行return,并停止查找。如果找不到会显示undefined

let arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.find(function(value,index,arr){
    return value > 5;
}))
// 6
  • fill()方法

fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的位置,第三个是填充结束的位置。

let arr=[0,1,2,3,4,5,6,7,8,9];
arr.fill('hh',2,5);
console.log(arr); //[0, 1, "hh", "hh", "hh", 5, 6, 7, 8, 9]
  • 数组的遍历
// for...of循环
for(let item of arr){
  console.log(item)
}

//for...of输出数组索引
for(let index of arr.keys()){
  console.log(index)  //0,1,2
}

//同时输出内容和索引
for(let [index,item] of arr.entries()){
  console.log(index + item)
}
  • entries()实例方法

entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。

let arr=['hello','world','hh']
let list=arr.entries();
console.log(list.next().value);
console.log(list.next().value);
console.log(list.next().value);

ES6中箭头函数和扩展

  • 默认值 函数多个参数,可以给其中的参数设置默认值,传参时不必要传
  • 主动抛出错误 使用 throw new Error(”)
  • 严谨模式 在函数体头部 ‘use strict’
  • 获得需要传递的参数个数 function.length
  • 箭头函数 () => {} ,与普通函数区别是this指向外部环境

ES6中的函数和数组补漏

  • 对象的函数解构
let json = {
    a:'hello',
    b:'world'
}
function fun({a,b}){
    console.log(a,b);
}
fun(json);
  • 数组的函数解构
let arr = ['hello','world','hh'];
function fun(a,b,c){
    console.log(a,b,c);
}
fun(...arr);
  • in的用法
//对象判断
let obj={
    a:'hello',
    b:'world'
}
console.log('a' in obj);  //true

//数组判断
//这里的0指的是数组下标位置是否为空
let arr=[,,,,,];
console.log(0 in arr); //false

let arr1=['jspang','技术胖'];
console.log(0 in arr1);  // true
  • 数组的遍历方法
// forEach
let arr=['hello','world','hh'];
arr.forEach((val,index)=>console.log(index,val));

//filter
arr.filter(x=>console.log(x));

// some
arr.some(x=>console.log(x));

// map
arr.map(x=>console.log(x));
// console.log(arr.map(x=>'web'));
  • 数组转换字符串
//join() 在数组中加入间隔
let arr=['hello','world','hh'];
console.log(arr.join('|'));

// toString() 转换时用,隔开
console.log(arr.toString())

ES6中对象

  • 对象赋值

ES6允许把声明的变量直接赋值给对象

let name="hello";
let skill= 'web';
var obj= {name,skill};
console.log(obj);  //Object {name: "hello", skill: "web"}
  • 对象Key值构建

对于不知道key名的,可以用[ ] 的形式,进行对象的构建。

let key='skill';
var obj={
    [key]:'web'
}
console.log(obj.skill);
  • 自定义对象方法
var obj={
    add:function(a,b){
        return a+b;
    }
}
console.log(obj.add(1,2));  //3
  • Object.is()对象比较
var obj1 = {name:'hello'};
var obj2 = {name:'hello'};
console.log(obj1.name === obj2.name);//true
console.log(Object.is(obj1.name,obj2.name)); //true

// 区分=== 和 is方法,===为同值相等,is()为严格相等
console.log(+0 === -0);  //true
console.log(NaN === NaN ); //false
console.log(Object.is(+0,-0)); //false
console.log(Object.is(NaN,NaN)); //true
  • Object.assign()合并对象
var a={a:'hello'};
var b={b:'world'};
var c={c:'web'};

let d=Object.assign(a,b,c)
console.log(d); //{a: "hello", b: "world", c: "web"}

Symbol在对象中的作用

Symbol的意思是全局标记

  • 声明Symbol
var a = new String;
var b = new Number;
var c = new Boolean;
var d = new Array;
var e = new Object;
var f= Symbol();
console.log(typeof(f)); //symbol
  • Symbol的打印
var g = Symbol('hello');
console.log(g); //Symbol(hello)
console.log(g.toString());
  • Symbol在对象中的应用

用Symbol构建对象的Key,并调用和赋值。

var hello = Symbol();
var obj={
    [hello]:'Hello'
}
console.log(obj[hello]);
obj[hello]='web';
console.log(obj[hello]);
  • Symbol对象元素的保护作用

在对象中有很多值,但是循环输出时,并不希望全部输出,那我们就可以使用Symbol进行保护

//没有保护的写法
var obj={name:'hh',skill:'web',age:18};
for (let item in obj){
    console.log(obj[item]);
}

// 用Symbol进行保护
let obj={name:'hh',skill:'web'};
let age=Symbol();
obj[age]=18;
for (let item in obj){
    console.log(obj[item]); //hh web
}
console.log(obj[age]); // 18

Set和WeakSet数据解构

Set的数据结构是以数组的形式构建的。Set.size可以得到Set值的数量

  • Set声明
let setArr = new Set(['hello','world','hh','hello']);
// Set会去重
console.log(setArr);//Set {"hello", "world", "hh"}
  • Set值的增删查
//add追加。
let setArr = new Set(['hello','world','web']);
setArr.add('前端职场');
console.log(setArr);

//delete删除
setArr.delete('前端职场');
console.log(setArr);

//has查找
console.log(setArr.has('hello'));//true

//clear清空
setArr.clear();
console.log(setArr);//Set(0) {}
  • WeakSet的声明

WeakSet里边的值也是不允许重复的

// 直接在new 的时候就放入值,将报错
let weakObj=new WeakSet();
let obj={a:'hello',b:'world'}
weakObj.add(obj);
console.log(weakObj);

map数据结构

在一些构建工具中是非常喜欢使用map这种数据结构来进行配置的,因为map是一种灵活,简单的适合一对一查找的数据结构。

  • Json和map格式的对比

map的效率和灵活性更好,你可以把它看成一种特殊的键值对,但你的key可以设置成数组,值也可以设置成字符串,让它不规律对应起来。

let json = {
    name:'hello',
    skill:'web'
}
console.log(json.name);

var map=new Map();
map.set(json,'hello');
// map.set('hello',json)
console.log(map);
  • map的增删查
// 增加set
map.set(json,'hello');

// 取值get
console.log(map.get(json));

// 删除delete
map.delete(json);
console.log(map)

// size取长度
console.log(map.size);

// has查找
console.log(map.has('hello'))

// clear清空
map.clear()

用Proxy进行预处理

在运行函数前初始化一些数据,在改变对象值后做一些善后处理。这些都算钩子函数,Proxy的存在就可以让我们给函数加上这样的钩子函数,你也可以理解为在执行方法前预处理一些代码。你可以简单的理解为他是函数或者对象的生命周期。
Proxy的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。

  • 声明Proxy

第一个花括号就相当于我们方法的主体,后边的花括号就是Proxy代理处理区域,相当于我们写钩子函数的地方。

// 基本形式
// new Proxy({},{});

var pro = new Proxy({
    add: function (val) {
        return val + 10;
    },
    name: 'I am hh'
}, {
        get:function(target,key,property){
            console.log('come in Get');
            return target[key];
        }
    });

console.log(pro.name); // come in Get, I am hh
  • get属性

get属性是在你得到某对象属性值时预处理的方法,他接受三个参数

target:得到的目标值
key:目标的key值,相当于对象的属性
property:这个不太常用,用法还在研究中,还请大神指教。

  • set属性

set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。

target:目标值。
key:目标的Key值。
value:要改变的值。
receiver:改变前的原始值。

var pro = new Proxy({
    add: function (val) {
        return val + 10;
    },
    name: 'I am hh'
}, {
        get:function(target,key){
            console.log('come in Get');
            return target[key];
        },
        set:function(target,key,value,receiver){
            console.log(`setting ${key} = ${value}`);
            return target[key] = value;
        }

    });

console.log(pro.name); // come in Get,I am hh
pro.name='zust'; // setting name = zust
console.log(pro.name); // come in Get,zust
  • apply的使用

apply的作用是调用内部的方法,它使用在方法体是一个匿名函数时。

let target = function () {
    return 'I am hh';
};
var handler = {
    apply(target, ctx, args) {
        console.log('do apply');
        return Reflect.apply(...arguments);
    }
}

var pro = new Proxy(target, handler);

console.log(pro()); // do apply,I am hh

promise对象的使用

ES6中的promise的出现给我们很好的解决了回调地狱的问题,在使用ES5的时候,在多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发,ES6认识到了这点问题,现在promise的使用,完美解决了这个问题。那我们如何理解promise这个单词在ES5中的作用那,你可以想象他是一种承诺,当它成功时执行一些代码,当它失败时执行一些代码。它更符合人类的行为思考习惯,而不在是晦涩难懂的冰冷语言。

  • promise的基本用法

promise执行多步操作非常好用,那我们就来模仿一个多步操作的过程,那就以吃饭为例吧。要想在家吃顿饭,是要经过三个步骤的。

1.洗菜做饭。
2.坐下来吃饭。
3.收拾桌子洗碗。
这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。我们可以在脑海里先想想这样一个简单的过程在ES5写起来就要有多层的嵌套。那我们现在用promise来实现。

let state=1;

function step1(resolve,reject){
    console.log('1.开始-洗菜做饭');
    if(state==1){
        resolve('洗菜做饭--完成');
    }else{
        reject('洗菜做饭--出错');
    }
}


function step2(resolve,reject){
    console.log('2.开始-坐下来吃饭');
    if(state==1){
        resolve('坐下来吃饭--完成');
    }else{
        reject('坐下来吃饭--出错');
    }
}


function step3(resolve,reject){
    console.log('3.开始-收拾桌子洗完');
     if(state==1){
        resolve('收拾桌子洗完--完成');
    }else{
        reject('收拾桌子洗完--出错');
    }
}

new Promise(step1).then(function(val){
    console.log(val);
    return new Promise(step2);

}).then(function(val){
     console.log(val);
    return new Promise(step3);
}).then(function(val){
    console.log(val);
    return val;
});

class类的使用

我们在ES5中经常使用方法或者对象去模拟类的使用,虽然可以实现功能,但是代码并不优雅,ES6为我们提供了类的使用。需要注意的是我们在写类的时候和ES5中的对象和构造函数要区分开来,不要学混了。

  • 类的声明
class coder{
    name(val){
        console.log(val);
    }
}
  • 类的使用

实例化类,并使用类中的方法

class Coder{
    name(val){
        console.log(val);
    }
}

let hh= new Coder;
hh.name('hh');
  • 类的多方法声明

注意的是两个方法中间不要写逗号了,还有这里的this指类本身,还有要注意return 的用法

class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('hh')+':'+'Skill:'+val);
    }
}

let hh= new Coder;
hh.name('hh');
hh.skill('web');
  • 类的传参

在类的参数传递中我们用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。

class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('hh')+':'+'Skill:'+val);
    }

    constructor(a,b){
        this.a=a;
        this.b=b;
    }

    add(){
        return this.a+this.b;
    }
}

let hh=new Coder(1,2);
console.log(hh.add());

我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加。这和以前我们的传递方法有些不一样,所以需要小伙伴们多注意下。

  • class的继承
class htmler extends Coder{

}

let hh=new htmler;
hh.name('hh');

声明一个htmler的新类并继承Coder类,htmler新类里边为空,这时候我们实例化新类,并调用里边的name方法。结果也是可以调用到的。

模块化操作

在ES5中我们要进行模块华操作需要引入第三方类库,随着前后端分离,前端的业务日渐复杂,ES6为我们增加了模块话操作。模块化操作主要包括两个方面。

export :负责进行模块化,也是模块的输出。
import : 负责把模块引,也是模块的引入操作。

  • export的用法

export可以让我们把变量,函数,对象进行模块话,提供外部调用接口,让外部进行引用。先来看个最简单的例子,把一个变量模块化。我们新建一个temp.js文件,然后在文件中输出一个模块变量。

// temp.js
export var a = 'hh';

// index.js
import {a} from './temp.js';
console.log(a);
  • 多变量的输出

这里声明了3个变量,需要把这3个变量都进行模块化输出,这时候我们给他们包装成对象就可以了

var a ='hello';
var b ='hh';
var c = 'web';

export {a,b,c}
  • 函数的模块化输出
export function add(a,b){
    return a+b;
}
  • as的用法

有些时候我们并不想暴露模块里边的变量名称,而给模块起一个更语义话的名称,这时候我们就可以使用as来操作

var a ='hello';
var b ='hh';
var c = 'web';

export {
    x as a,
    y as b,
    z as c
}
  • export default的使用

加上default相当是一个默认的入口。在一个文件里export default只能有一个。我们来对比一下export和export default的区别

1.export

export var a ='hh';

export function add(a,b){
    return a+b;
}

对应的导入方式

import {a,add} form './temp';//也可以分开写

2.export default

export default var a='jspang';

对应的引入方式

import str from './temp';

ES6的模块化不能直接在浏览器中预览,必须要使用Babel进行编译之后正常看到结果。

你可能感兴趣的:(javascript,面试)