ES6常用特性

212 阅读6分钟

1:const,let,var

var声明变量存在变量提升,而let和const不存在变量提升

        console.log(a);   //undefined    在声明前进行控制台输出  可以输出  但是输出的是undefined
        var a = '张三';
        console.log(a);   //张三          在声明之后进行控制台输出   可以输出结果
        
        //而用const和let声明变量时,无法进行变量提升,此事会直接报错
        console.log(b);
        const b='李四';
        
        console.log(c);
        let c='王五';
function fn() {
   //var a
    if (true) {
        console.log(a + ' now')
    }
    else {
        var a = 1
        console.log(2)
    }
}
fn() // a -> undefined            输出结果为undefined  now   var a被变量提升到了if之前   但是提升的仅仅是  var a   而不是 var a=1   因此在if语句中打印的是undefined  +now

let和const都是块级局部变量(只在当前代码块当中起作用)

{
let/const a=1; 
}
console.log(a);  //都会显示a is not defined

而const和let的特性一样,不同的是

  1. const声明的时候要先赋值
  2. const只能进行一次赋值,赋值之后不能改变
  3. 如果声明的是复合类型数据,可以修改其属性
  4. let 和 const 声明只在最靠近的一个块中(花括号内)有效

同一作用域下let和const不能声明同名变量,而var可以

        const a = 2
        const a = 1    //Identifier 'a' has already been declared  标识符“a”已声明

面试题

for (let i = 0; i < 5; i++) {
    console.log(i)
}    //打印的是0,1,2,3,4

参考:

www.jianshu.com/p/7bf685dbc…

2:模板字符串

学习ES6之前,在处理字符串的时候往往通过“\”和“+”进行拼接字符串

$("body").html("This demonstrates the output of HTML \
content to the page, including student's\
" + name + ", " + seatNumber + ", " + sex + " and so on.");

而ES6中

  1. 基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;
  2. ES6反引号(``)直接搞定;
        //ES6引入新的声明字符串方式      ``
        // 1.声明
        let str=`我是叶念`;
        console.log(str,typeof str);

        // 2.内容中可以直接出现换行符
        // 3.直接进行变量的拼接
        let love='学习';
        let my=`${love}是我的最爱`;
        console.log(my);   //会直接显示“学习是我的最爱”

同时对于模板字符串需要注意的是: 模板字符串中的换行和空格都是会被保留的 如下所示:

innerHtml = `<ul>
  <li>menu</li>    <li>mine</li>
</ul>
`;
console.log(innerHtml);    因为两个li没有分行  且li之间有空格  因此控制台输出的结果为:
<ul>
  <li>menu</li>    <li>mine</li>
</ul>

标签模板

标签模板,是一个函数的调用,其中调用的参数是模板字符串。

alert`Hello world!`;
// 等价于
alert('Hello world!');

3:常用运算符

ES6中常用的有扩展、剩余运算符,使用“...”,后面跟着一个含有iterator接口的数据结构

扩展运算符

以数组为例,使用扩展运算符使得可以"展开"这个数组,可以这么理解,数组是存放元素集合的一个容器,而使用扩展运算符可以将这个容器拆开,这样就只剩下元素集合,你可以把这些元素集合放到另外一个数组里面

  1. 扩展运算符将数组转换为用逗号分割开的参数序列
        // 扩展运算符将数组转换为逗号分割的参数序列
        // 声明一个数组
        const boy=['张三','李四','王五'];
        // 声明一个函数
        function shuchu(){
            console.log(arguments);
        }
        console.log(...boy);    //在控制台输出   张三 李四 王五
  1. 扩展运算符也可以用作数组的合并
        // 数组的合并
        const arr1=[1,2,3];
        const arr2=[4,5,6];
        // const a1=arr1.concat(arr2);<==>
        const a1=[...arr1,...arr2]
        console.log(a1);  //在控制台输出   [1,2,3,4,5,6]
  1. 扩展运算符用于数组的克隆
        // 数组的克隆
        const bgm=['e','g','m'];
        const bg=[...bgm];
        console.log(bg);   //在控制台输出 ["e", "g", "m"]
  1. 扩展运算符将伪数组转换为真正的数组
    <div></div>
    <div></div>
    <div></div>
    <script>
     /*利用扩展运算符将伪数组转成真数组*/
    var oDivs= document.getElementsByTagName('div');
    console.log(oDivs)
    console.log( oDivs instanceof Array)  //判断是不是真数组
 
    let arr =[...oDivs];
    console.log(arr)
    console.log(arr instanceof Array)
    </script>

使用扩展运算符可以快速的将类数组转为一个真正的数组,合并多个数组,克隆数组和将伪数组转换为真数组

剩余运算符

剩余运算符最重要的一个特点就是替代了以前的arguments 访问函数的arguments对象是一个很昂贵的操作,以前的arguments.callee,arguments.caller都被废止了,建议在支持ES6语法的环境下不要在使用arguments对象,使用剩余运算符替代(箭头函数没有arguments,必须使用剩余运算符才能访问参数集合)。

        function func(a,b,c){
            console.log(arguments[0],arguments[1],arguments[2]);
        }
        func(1,2,3)
        //rest是形参,承载了所有的函数参数,可以随意取名
        function func1(...rest){
            console.log(rest);
        }
        func1(1,2,3)

剩余运算符可以和数组的解构赋值一起使用,但是必须放在最后一个,因为剩余运算符的原理其实是利用了数组的迭代器,它会消耗3个点后面的数组的所有迭代器,读取所有迭代器生成对象的value属性,剩运算符后不能在有解构赋值,因为剩余运算符已经消耗了所有迭代器,而数组的解构赋值也是消耗迭代器,但是这个时候已经没有迭代器了,所以会报错。 剩余运算符和扩展运算符的区别就是,剩余运算符会收集这些集合,放到右边的数组中,扩展运算符是将右边的数组拆分成元素的集合,它们是相反的。

4:箭头函数

在ES6中,箭头函数就是函数的一种简写形式,通过“=>”来定义函数

箭头函数最直观的三个特点

  1. 不需要function关键字来创建函数
  2. 省略return关键字
  3. 继承当前上下文的this关键字
        //省略小括号   当形参只有一个的时候
        let add=n=>{
            return n+n;
        }
        console.log(add(1));
        //省略花括号   当代码题只有一条语句的时候
        let pow=(n)=>n*n;
        
        console.log(pow(2));

细节:当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略{} 和 return;

箭头函数对于使用function关键字创建的函数有以下区别

  1. 箭头函数没有arguments(建议使用更好的语法,剩余运算符替代)
         // 不能使用arguments变量
        let fn=()=>{
            console.log(arguements);
        }
        fn(1,2,3);   //arguements is not defined
  1. 箭头函数没有prototype属性,不能用作构造函数(不能用new关键字调用)
  2. 箭头函数没有自己this,它的this是词法的,引用的是上下文的this,即在你写这行代码的时候就箭头函数的this就已经和外层执行上下文的this绑定了(这里个人认为并不代表完全是静态的,因为外层的上下文仍是动态的可以使用call,apply,bind修改,这里只是说明了箭头函数的this始终等于它上层上下文中的this)
//      箭头函数的this是静态的   this始终指向函数声明时所在作用域下的this的值   call,apply,bind无法改变this指向
        function getname(){
            console.log(this.name);
        }
        let getname2=()=>{
            console.log(this.name);
        }
        window.name="张三";
        const names={
            name:"李四"
        }
        // 直接调用
        // getname();     //张三
        // getname2();    //张三
        
        // 采用call方法更改this指向
        getname.call(names);   //李四
        getname2.call(names);  //张三..

因为setTimeout会将一个匿名的回调函数推入异步队列,而回调函数是具有全局性的,即在非严格模式下this会指向window,就会存在丢失变量a的问题,而如果使用箭头函数,在书写的时候就已经确定它的this等于它的上下文(这里是makeRequest的函数执行上下文,相当于将箭头函数中的this绑定了makeRequest函数执行上下文中的this)因为是controller对象调用的makeRequest函数,所以this就指向了controller对象中的a变量

        // 从数组中返回偶数的元素
        const arr = [1, 2, 3, 4, 5, 6, 7, 8];
        const result = arr.filter(item => item % 2 === 0);
        console.log(result);
<style>
        div {
            width: 200px;
            height: 200px;
            background: red;
        }
    </style>
</head>

<body>
    <div id="ad">

    </div>
    <script>
        // 箭头函数适合与this无关的毁掉,定时器、数组的方法回调
        // 箭头函数不适合与this有关的回调   事件回调,对象的方法
        // 点击div  2s之后颜色改变
        // 获取元素
        let ad = document.getElementById('ad');
        // 绑定事件
        ad.addEventListener("click", function () {
            // 保存this的值
            // let _this=this;
            // setTimeout(function(){
            //     // 修改背景颜色  用this来修改
            //     _this.style.background='pink'
            // },2000)<===>
            setTimeout(() => {
                this.style.background = 'pink';
            }, 2000)
            // 箭头函数this是静态的指向在声明时所在作用域下的this指向
        })
        
    </script>
</body>

注意

箭头函数替代了以前需要显式的声明一个变量保存this的操作,使得代码更加的简洁

箭头函数的this指向即使使用call,apply,bind也无法改变

不要在可能改变this指向的函数中使用箭头函数,类似Vue中的methods,computed中的方法,生命周期函数,Vue将这些函数的this绑定了当前组件的vm实例,如果使用箭头函数会强行改变this,因为箭头函数优先级最高(无法再使用call,apply,bind改变指向)

全文参考:

juejin.cn/post/684490…