JavaScript ES6-11常用新语法

let声明变量

  1. 在js中,使用var声明的变量往往会越域,而使用let声明的变量,会形成独立的块级作用域。
  2. var可以给一个变量声明多次,而let只能声明一次。
  3. var会变量提升,let不存在变量提升
//let 形成独立的块级作用域,在当前内部没有值,会向上找
{
    var a = 1;
    let b = 2;
}
console.log(a);  // 1
console.log(b);  // ReferenceError: b is not defined
 
//var 可以声明多次
// let 只能声明一次
var m = 1
var m = 2
let n = 3
let n = 4
console.log(m)  // 2
console.log(n)  // Identifier 'n' has already been declared
 
// var 会变量提升
// let 不存在变量提升
console.log(x);  // undefined
var x = 10;
console.log(y);   //ReferenceError: y is not defined
let y = 20;
暂时性死区
if(true){
// temp = 'abc';   // 暂时性死区 简称 TDZ(temporal dead zone)
// console.log(temp);
let temp; // TDZ 结束
console.log(temp); // undefined
temp = 123;
console.log(temp); // 123
}

const声明变量

  1. 声明之后不允许改变
  2. 一旦声明必须初始化,否则会报错
  3. 类似于let
const a = 1;
a = 3; //Uncaught TypeError: Assignment to constant variable

解构表达式

数组解构
let arr = [1,2,3];
// 以前想要获取其中的值,只能通过下标,在ES6中可以这样
const [x,y,z] = arr; // x,y,z将与arr中的每个位置对应来取值
// 打印
console.log(x,y,z);//1,2,3
对象解构
基本用法
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
//对象解构  解构表达式获取值
const { name, age, language } = person;

// 等价于下面的表示方式
// const name = person.name;
// const age = person.age;
// const language = person.language;

console.log(abc, age, language)
解构赋值
// 如果想要将name的值赋给其他变量,可以使用如下形式,username是新的变量名
const { name:username, age, language } = person;
console.log(username);

字符串扩展

新增API
  1. includes(str):返回布尔值,表示是否找到了指定的字符串
  2. startsWith(str):返回布尔值,表示指定字符串是否在原字符串的头部
  3. endsWith(str):返回布尔值,表示指定字符串是否在原字符串的尾部
let str = "hello.vue";
console.log(str.startsWith("hello"));//true
console.log(str.endsWith(".vue"));//true
console.log(str.includes("e"));//true
console.log(str.includes("hello"));//true
字符串模板

模板字符串相当于加强版的字符串,用反引号 ` ,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式

const person = {
name: "jack",
age: 21
} 
const { name, age} = person;
let info = `我是${name},今年${age}`;
console.log(info);

函数优化

函数参数的默认值
//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
// 判断b是否为空,为空就给默认值1
b = b || 1;
return a + b;
}
// 传一个参数
console.log(add(10));
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
console.log(add2(20));
rest参数

es6引入的rest参数,形式为(…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了,rest搭配的的变量是一个数组,这个变量,将多余的参数放入数组中

function push(array,...items){
items.forEach(function(item){
array.push(item);
console.log(array); 
})
}
var a = []; 
push(a,1,2,3,4); 
// 注意:rest参数之后不能再有其他的参数(也就是rest参数只能是最后一个参数)
箭头函数
// 基本用法
var f = function (v) {
return v;
}
console.log(f(1));

// 箭头函数  
var t = v => v;
console.log(t(9));

var y = () => 5; // var y = function () { retiunr 5  }
console.log(y());

var sum = (num1, num2) => num1 + num2; // var sum = function(num1,num2){ return num1 + num2 }
console.log(sum(1, 2));

let getS = id => ({ id: id, name: '张三' });
let num = () => { a: 1 }; //  undefined 

const fll = ({ a, b }) => a + '--' + b;
console.log(fll({ a: 1, b: 2 }));

// 1、如果是一个参数,可以不使用小括号,直接传入 
// 2、 如果是返回一个值,可以省略return (只有一行代码的时候)
// 3、如果没参数,或者有多个参数,就使用小括号
// 4、如果返回的是一个对象 必须在对象外面加上圆括号 ,否则会报错
var handler = {
id: '123456',
init: function () {
document.addEventListener('click', function (event) { this.doSomeing(event.type) }, false)
},
doSomeing: function (type) {
console.log((type + '--' + this.id));
}
}
handler.init();

// 箭头函数中的this的指向,为什么是固定化的  
//    答案:不是因为箭头函数中内部有绑定的this,实际上是因为,箭头函数,根本就没有this
//    导致内部的this,就是外层代码的this
不适用箭头函数的场合

第一个场合,定义对象的方法,并且对象的方法内包括this

const obj = {
ai:9,
// lack:function(){
//     console.log(this);
// }

lack:()=>{
console.log(this); // window 
}
}
obj.lack(); 

之前使用的是动态的this,箭头函数是静态的this

第二种场合,需要使用动态this的时候,不能使用箭头函数

var btn = document.getElementById('button'); 
btn.addEventListener('click',()=>{
this.classList.toggle('on'); // window
})

如果函数体很复杂,有很多行,有大量的操作,不是为了计算值,这个时候,也不要使用箭头函数,使用普通函数就可以了

Generator函数

这个是es6提供的一种异步编程的解决方案,语法行为和传统函数不一样

在理解上,可以理解为是一种状态机,里面封装的是多个内部状态 ,Generator函数会返回一个遍历器对象,这个对象可以依次遍历Generator函数内部的每一个状态。

Generator函数和传统函数比较:

  1. 在function关键字后面多了一个星号
  2. 在函数体内部,使用的是yield表达式,定义不同的内部状态

可以解决回调地狱问题

function* hello() {
yield 'hello'
yield 'world'
return 'edning'
}
var hw = hello();
// console.log(hello());

// 调用方式 
//done属性的值是true,表示遍历就结束了
console.log(hw.next());//{done:false,value:"hello"}
console.log(hw.next());//{done:false,value:"world"}
console.log(hw.next());//{done:true,value:"edning"}
console.log(hw.next());//{done:true,value:undefined}

对象优化

新API

ES6给Object扩展了许多新方法:

  1. keys(obj):获取对象的所有key形成的数组
  2. values(obj):获取对象的所有value形成的数组
  3. entries(obj):获取对象的所有key和value形成的二维数组。
  4. assign(dest,…src):将多个src对象的值拷贝到dest中。(第一层为深拷贝,第二层为浅拷贝)
const person = {
      name: "jack",
      age: 21,
      language: ['java', 'js', 'css']
}
 
console.log(Object.keys(person));//["name", "age", "language"]
console.log(Object.values(person));//["jack", 21, Array(3)]
console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]
  
// assign
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
 
//{a:1,b:2,c:3}
Object.assign(target, source1, source2);
 
console.log(target);//["name", "age", "language"]
声明对象简写
const age = 23
const name = "张三"
// 之前写法
const person1 = { age: age, name: name }
 
// 简写(如果属性名与属性值的变量名一样,就可以简写,例如person的属性名age,变量age,名称一样,所以可以简写)
const person2 = { age, name }        // 意思是:person2有一个属性age,它的属性值为age变量,name同理
console.log(person2);

对象扩展运算符

扩展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象

// 1、拷贝对象(深拷贝)
let p1 = { name: "Amy", age: 15 }
let someone = { ...p1 }
console.log(someone)  //{name: "Amy", age: 15}
 
// 2、合并对象
let age1 = { age: 15 }
let name1 = { name: "Amy" }
p2 = { ...age1, ...name1 }   // 将age1对象的所有的属性值拷贝给p2,将name1对象的所有的属性值拷贝给p2对象
console.log(p2)

注意:如果两个对象的字段名重复,后面对象的字段值会覆盖前面对象的字段值

数组的新方法

map函数

接收一个函数,将原数组的所有元素用这个函数处理后放入一个新的数组返回

let arr = ['1', '20', '-5', '3'];
// 将数组中的每个元素 x2 返回
arr = arr.map(item=> item*2);
console.log(arr);

Promise

Promise可以封装异步操作

  1. Promis 创建

    const promise = new Promise((resolve, reject) =>{
    // 异步处理
    // 处理结束后、调用resolve 或 reject
    });
    //Promise 构造函数包含一个参数和一个带有 resolve(解析)和 reject(拒绝)两个参数的回调。在回调中执行一些操作(例如异步),如果一切都正常,则调用 resolve,否则调用 reject。
    
  2. Promise Ajax

    function ajax(URL) {
        return new Promise(function (resolve, reject) {
            var req = new XMLHttpRequest(); 
            req.open('GET', URL, true);
            req.onload = function () {
            if (req.status === 200) { 
                    resolve(req.responseText);
                } else {
                    reject(new Error(req.statusText));
                } 
            };
            req.onerror = function () {
                reject(new Error(req.statusText));
            };
            req.send(); 
        });
    }
    var URL = "/try/ajax/testpromise.php"; 
    ajax(URL).then(function onFulfilled(value){
        document.write('内容是:' + value); 
    }).catch(function onRejected(error){
        document.write('错误:' + error); 
    });
    
  3. Promise.then()方法:链式操作

    Promise.then()方法返回的是一个新的Promise对象,因此可以采用链式写法

    getJSON("/posts.json").then(function(json) {
    return json.post;
    }).then(function(post) {
    // proceed
    });
    
  4. Promise.catch()方法:捕获错误

    Promise.catch()方法时Promise.then(null,rejection)的别名,用于指定发送错误时的回调函数。

    getJSON("/posts.json").then(function(posts) {
    // some code
    }).catch(function(error) {
    // 处理前一个回调函数运行时发生的错误
    console.log('发生错误!', error);
    });
    
  5. Promise.all()方法

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.all([p1, p2, p3]);
    

    (1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

    (2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

  6. Promise.finally()方法

    finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

    promise
    .then(result => {···})
    .catch(error => {···})
    .finally(() => {···});
    
Promise的all、any、race、allSettled方法的区别
一、共同点
  1. 这些方法的参数都接受一个Promise的iterable类型(Array,Map,Set都属于ES6的iterable类型)的输入
  2. 这些方法都返回一个Promise的实例
二、各方法之间的区别

then和catch都会返回一个新的promise

catch不管连接到哪里,都能捕获上层未捕捉过的错误

then和catch可以被调用多次,但如果promise内部的状态一经改变,并且有一个值,那么后续每次调用then或者catch的时候都会直接拿到该值

then和catch返回的值不能是promise的本身,否则会造成死循环

then和catch的参数都是函数,传入非函数会发生透值

finally方法返回的也是一个promise,在promise结束的时候无论结果为resolved还是rejected,都会执行里面的回调函数

finally方法不管是promise对象的状态是什么都会执行

finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected

它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常的Promise对象。

Set

  1. 基本使用

    s6提供了新的数据结构Set,类似于数组,但是成员值是唯一的,也就是没有重复的值

    Set是一个构造函数,用来生成set的数据结构

    是可以接受一个参数的 参数:可以是一个数组,或者是iterable接口的其他数据结构

    自动去重

    const set = new Set([1, 5, 3, 4, 6, 2, 2, 4]); // 参数是数组
    const set1 = new Set(document.querySelectorAll('div')); // 参数是类似数组的对象
    console.log(new Set('abababa')); // 字符串去重
    

    注意:跟普通的数据类型是一样的,比如6和’6’是不一样的

    let set2 = new Set();
    // 相当于运行了 === 
    let a = NaN;
    let b = NaN;
    set2.add(a);
    set2.add(b);
    console.log(set2);   //Set(1) {NaN}
    console.log(NaN === NaN);//false
    // 对象总是不相等的  
    let set3 = new Set();
    set3.add({ name: "李四" });
    set3.add({ name: '张三' })
    console.log(set3);      //Set(2) {{…}, {…}}
    set3.forEach(x => console.log(x.name))//李四  张三
    
  2. 属性

    Set.prototype.constructor: 构造函数,默认就是Set函数

    Set.prototype.size: 返回的是Set实列成员的个数

  3. 操作方法 – 用于操作数据

    Set.prototype.add(value): 添加某个值,返回的是Set结构本身

    Set.prototype.delete(value): 删除某一个值,返回值是一个布尔值,表示是否删除成功

    Set.prototype.has(value): 返回一个布尔值,表示值是否是Set的成员

    Set.prototype.clear(): 清除所有的数据,没有返回值 – 使用请慎重

    let s = new Set();
    let s2 = new Set(['A','B','C','D'])
    //元素个数
    console.log(s2.size);
    //添加新的元素
    s2.add('E');
    //删除元素
    s2.delete('A')
    //检测
    console.log(s2.has('C'));
    //清空
    s2.clear()
    console.log(s2);
    
  4. 遍历方法 – 用于遍历数据成员

    Set.prototype.keys():返回键名的遍历器

    Set.prototype.values():返回键值的遍历器

    Set.prototype.entries():返回键值对的遍历器

    Set.prototype.forEach(): 使用回调函数遍历每个成员

    let set5 = new Set(['red', 'green', 'blue']);
    
    for (let key of set5.keys()) {
    console.log(key);//red  green  blue
    }
    for (let key of set5.values()) {
    console.log(key);//red  green  blue
    }
    // 因为Set结构,没有键名,只有键值(理解为键名何键值是同一个值)
    for (let key of set5.entries()) {
    console.log(key);// ['red', 'red']  ['green', 'green']   ['blue', 'blue']
    }
    
    let set6 = new Set([1,3,5])
    set6.forEach( (value,key)=> console.log(value + '---' + key))//1---1 3---3 5---5
    

Map

javascript对象(Object),本质上是键值对的集合(Hash结构)

为了解决对象的键是一个字符串,es6提供了Map() 数据结构

类似对象,也是键值对的集合,但是要注意的是,键的范围 不限制于是字符串,各种类型的值,都可以做 键 名

Object实现了 字符串 – 值 方式,但是Map结构实现了 值 - 值 的对应,是一种更加完善的Hash结构

let m = new Map();
m.set('name','ran');
m.set('change',()=>{
console.log('改变!')
})
let key={
school:'atguigu'
}
m.set(key,['成都','西安']);
//size
console.log(m.size);//3
//删除
console.log( m.delete('name'));//true
//获取
console.log(m.get('change'));
//()=>{
//       console.log('改变!')
//   }
// //清空
// m.clear()
//遍历
for(let v of m){
console.log(v);//['change', ƒ]    
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值