关于学习中遇到的E6新增特性

一,变量声明:Letconst

ES6推荐使用Let来声明变量,Let提供块作用域(block-scoping),这会比var提供的以函数为作用域有更加精细化的控制。请看下面例题

问:在下面程序中,控制台打印的最终结果?

    function fn() {
        var arr = [];
        for (var i = 0; i < 5; i++) {
            arr.push(function(){
                return console.log(i);
            })
        }
        return arr;
    }
    for (let i = 0; i < 5; i++) {
        fn()[i]()
    }
复制代码

你可能会误以为结果是[0,1,2,3,4],但实际却是[5,5,5,5,5]

var来定义一个变量,JavaScript在预先编译的时候会将变量提升至函数的顶部,经过5个for循环,arr里面的i会指向同一个i,此时函数中的i已经是5,所以最终结果也就是5了。

下面把for循环的var改为let:

    function fn() {
        var arr = [];
        for (let i = 0; i < 5; i++) {
            arr.push(function(){
                return console.log(i);
            })
        }
        return arr;
    }
    for (let i = 0; i < 5; i++) {
        fn()[i]()
    }
复制代码

结果输出[0,1,2,3,4],因为let拥有块作用域,所以使用let声明的变量i不会被提升到函数顶部,i的作用域在for循环, 就会每次循环有独立的值。

如果你想定义一个常量,请使用ES6里的constconst声明的变量是完全不可更改的。

    const PI = 3.14;
    PI = 1;
复制代码

结果是直接报错 Uncaught TypeError: Assignment to constant variable. at <anonymous>:3:4

关于letconst有几个点需要注意

  • let 关键词声明的变量不具备变量提升(hoisting)特性
  • let 和 const 声明只在最靠近的一个块中(花括号内)有效
  • 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
  • const 在声明时必须被赋值

二, 模板字符串

在ES6之前我们往往用+来处理模板字符串

    var str = 'I' + 'Have' + Num + 'Apple'
复制代码

而在ES6中基本的字符串格式化,将表达式嵌入字符串中进行拼接,用${}来界定;ES6反引号(``)直接搞定

    var str = `I Have ${Num} Apple`
复制代码

三, 箭头函数(Arrow Functions)

ES6中,箭头函数是函数的一种简写形式 () = >
箭头函数最直观的三个特点

  • 不需要function 关键字来创建函数
  • 省略return关键字
  • 当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略'{}' 和 'return';
    //ES5   
    var fn = function(x){
        return x
    }
    
    //ES6
    var fn = (x) = >{
        return x
    }
    
    //ES6简写
    var fn = x => x
复制代码

四, 对象的遍历:for...in

    //定义一个对象
    var Apple = {
        color: "red",
        weight: "50g",
        kind:function(){
            console.log("HongFuShi")
        }
    }
    
    //用for...in遍历对象
    for(let item in Apple){
        console.log(Apple[item])
    }
复制代码

五,ES6中的类class

ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。

class创建对象的格式:

    class 类名{
        constructor(参数){
            this.属性 = 参数;
        }
        method(){
            // 对象中简写方法,省略了function。不要与箭头函数搞混了
        }
    }
复制代码
  • 注意:ES6 中支持class语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式
  • ES6 中支持 class语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。
  • 方法和方法之间没有逗号。不是键值对

在ES5中,我们创建一个类通常如下:

    //创建一个构造函数
    function Apple (color,weight) {
        this.color = color;
        this.weight = weight;
    }
    //向函数原型写入方法
    Apple.prototype.getkind = function(){
        console.log('HongFuShi');
    }
    //创建新对象,并调用方法
    var Apple = new Apple("red","50g");
    console.log(Apple);
    Apple.getkind();
复制代码

在ES6中我们可以用class来声明一个类

    //创建一个类
    class Apple {
        //构造器
        constructor(color, weight) {
            this.color = color;
            this.weight = weight;
        }
        //类方法
        getkind(){
            console.log('HongFuShi');
        }
    }
    //创建新对象并调用属性方法
    var new_Apple = new Apple("red","50g");
    console.log(new_Apple);
    Apple1.getkind()
复制代码
  • 这里值得注意的是你new的对象名称不能与类的名称重复。

六,ES6里 类class 中的继承Extends

在ES5中我们继承属性是这样写的:

    //创建Apple构造函数
    function Apple (color,weight) {
        this.color = color;
        this.weight = weight;
    }
    //函数原型添加方法
    Apple.prototype.getkind = function(){
        console.log('HongFuShi');
    }
    //创建Smell_Apple构造函数
    function Smell_Apple (color,weight,smell) {
        Apple.call(this,color,weight); //利用call改变this指向,达到属性继承
        this.smell = smell;
    }
    //浅拷贝继承方法
    for (const key in Apple.prototype) {
        Smell_Apple.prototype[key] = Apple.prototype[key]
    }
    
    Smell_Apple.prototype.show = function(){
        console.log(`苹果的颜色是${this.color},重量是${this.weight},
        味道${this.smell}`);
    }
    
    //调用继承后的构造函数
    var new_Apple = new Smell_Apple("red","50g","good")
    console.log(new_Apple);
    new_Apple.getkind()
    new_Apple.show();
复制代码

在ES6中我们可以使用Extends来继承:

    //创建一个父类
    class Apple {
        constructor(color, weight) {
            this.color = color;
            this.weight = weight;
        }
        getkind(){
            console.log('HongFuShi');
        }
    }
    //子类继承父类
    class Smell_Apple extends Apple{
        constructor(color,weight,smell) {
            super(color,weight)
            this.smell = smell;
        }
        show(){
            console.log(`苹果的颜色是${this.color},重量是${this.weight},
            味道${this.smell}`);
        }
    }
    
    let new_Apple = new Smell_Apple("red","50g","good");
    console.log(new_Apple);
复制代码

七,ES6中新增的两种集合

我们在以往的ES版本中了解到了两种集合,arrobject ; ES6中我们又学到了两种新增的集合setmap

Set :

set和数组差不多,也是一种集合,区别在于:它里面的值都是唯一的,没有重复的。

    //创建一个set
    var arr = new Set([1,true,'hello',null,undefined,{name:'Apple'},function(){}])
    console.log(arr) //Set { 1, true, 'hello', null, undefined, { name: 'Apple' }, [Function] }
复制代码
  • 注意:创建set时,传多个参数时要用[]进行,单个可以用add()进行传参
var arr = new Set();
arr.add(1)
arr.add(true)
...
arr.add(function(){})
复制代码

遍历set有两种方式:
1 , forEach

var arr = new Set([1,true,'hello',null,undefined,{name:'Apple'},function(){}])
arr.forEach(vul => {
    console.log(vul);
});
复制代码

2 , for of

var arr = new Set([1,true,'hello',null,undefined,{name:'Apple'},function(){}])
for(let vul of arr){
    console.log(vul);
}
复制代码
  • 注意:
    1,set不是1数组,是一个像对象的伪数组
    2,set中的值是唯一的,数组中的值是不唯一的,不会重复
var arr = new Set([1,1,1,2,2,2])
console.log(arr);//输出Set { 1, 2 }

//利用以上特性我们可以很轻易的做到数组去重
var arr_one = [1,1,1,2,2,2]
var set_one = [...(new Set(arr_one))]
console.log(set_one) //输出[1,2]
复制代码
Map :

它类似于对象,里面存放也是键值对,区别在于:对象中的键名只能是字符串,如果使用map,它里面的键可以是任意值。

//创建一个Map
var M = new Map([
    ['a','Hello'],
    ['1','123']
]);
复制代码

使用set进行添加

var M = new Map();
M.set(false,'abc') //Map { false => 'abc' }
复制代码

通过get键来获取

var M = new Map([
    ['a','Hello'],
    ['1','123']
]);
M.get('a') // Hello
M.get('1') // 123
复制代码

八 , 字符串的扩展

1,模板字符串
2,其它的方法

(1) trim 去除字符串空格的。

  • trim 左右空格都是去掉
  • trimLeft 左空格去掉
  • trimRight 右空格去掉
let str = ' a ab abc ';

console.log(str);     
console.log(str.trim());    
console.log(str.trimLeft());
console.log(str.trimReft());
复制代码

(2) , repeat 顾名思义就是重复,可以把一个参数复制多份

let str = '123';
console.log(str.repeat(2)); //123123
console.log(str.repeat(3)); //123123123
复制代码

(3) , includes 查找当前字符串有没有指定的字符

let str = '123 abc';
console.log(str.includes('1'));//true
console.log(str.includes('a'));//true
复制代码

(4) , startWith 判断当前字符串是不是以指定字符开始的 endsWidth与之相反

let str = '123 abc';
console.log(str.startsWith('123'));  //true
console.log(str.startsWith('123a')); //false
console.log(str.endsWith('abc')); //true
console.log(str.endsWith('3abc')); //false
复制代码

(5) , padStartpadEnd,两个相反,可接受两个参数,第一个参数是预期的字符串长度,第二个参数是当字符串与预期长度不符时所填充的字符

let str = '123 abc';
console.log(str.padStart(10,'*'));//***123 abc
console.log(str.padEnd(10,'*')); //123 abc***
复制代码

九 , 严格模式

以下是严格模式中需要注意的用法,这里需要强调的是:ES6 的 class 和 模块内都是默认的严格模式。其实,js 开发也会逐步走向严格模式,这应该是个趋势。

s添加了保留字 protected,static 和 interface

1,在严格模式下,不可以用with()
    (function(){
      //非严格模式
      var a = {name: "Bob"};
      with(a){
        name = "Lily";
      }
      console.log(a.name);  //Lily
    })();

    (function(){
      "use strict";   //严格模式
      var a = {name: "Bob"}, b = {};
      with(a, b){    //SyntaxError: Strict mode code may not include a with statement
        name = "Lily";
      }
      console.log(a.name);
    })();
复制代码
2,在严格模式下,变量必须显示声明(var/let/const)
    (function(){
      //非严格模式
      a = 10;
      console.log(a);  //10
    })();

    (function(){
      "use strict";   //严格模式
      b = 10;   //ReferenceError: b is not defined
      console.log(b);
    })();
复制代码
3,在严格模式下,this默认是undefined
    (function(){
      //非严格模式
      console.log(this);  //window
    })();

    (function(){
      "use strict";   //严格模式
      console.log(this);    //undefined
    })();
复制代码
4,在严格模式下,为只读变量和不可扩展对象赋值会报错, 而不是静默失败
    (function(){
      //非严格模式
      var o = {
        name: "Lily"
      };
      Object.freeze(o);
      o.name = "Bob";
      o.age = 20;
      console.log(o);  //Object {name: "Bob"}
    })();

    (function(){
      "use strict";   //严格模式
        var o = {
        name: "Lily"
      };
      Object.freeze(o);
      o.name = "Bob";  //TypeError: Cannot assign to read only property 'name' of object '#&lt;Object&gt;'
      o.age = 20;  //TypeError: Can't add property age, object is not extensible
      console.log(o);
    })();
复制代码
5,在严格模式下,不可以在eval参数中定义变量和函数
    (function(){
      //非严格模式
      var str1 = "var name='Lily';";
      var str2 = "function fun1(){console.log('hello');}";
      eval(str1);   //这个name定义在了全局,而不是函数内
      eval(str2);
      console.log(name);   //Lily
      fun1();    //hello
    })();

    (function(){
      "use strict";   //严格模式
      var str1 = "var alias='Lily';";
      var str2 = "function fun2(){console.log('hello');}";
      eval(str1);
      eval(str2);
      eval("name = 'Bob'");    //修改全局变量name
      console.log(name);   //Bob
      console.log(alias);    //ReferenceError: alias is not defined
      fun2();    //ReferenceError: fun is not defined
    })();
复制代码
6,在严格模式下,有名参数是arguments参数的静态副本,而非引用。
    (function(){
      //非严格模式
      var name = "Bob";
      test(name);

      function test(alias){
        alias = "Lily";
        console.log(alias);  //Lily
        console.log(arguments[0]);  //Lily
      }
    })();

    (function(){
      "use strict";   //严格模式
      var name = "Bob";
      test(name);

      function test(alias){
        alias = "Lily";
        console.log(alias);  //Lily
        console.log(arguments[0]);  //Bob
      }
    })();
复制代码
7 ,在严格模式下,用delete删除var声明的变量和不可配置属性时抛出异常,而不是静默失败(返回false)
    (function(){
      //非严格模式
      var a = 10;
      var fun = function(){console.log("fun called");};
      var o = Object.defineProperty({}, "name", {
        value: "Bob"
      });   //默认即不可配置
      delete a;   //false
      console.log(a);  //10

      delete fun;   //false
      fun();  //fun called

      delete o.name;   //false
      console.log(o.name);  //Bob

      //删除一个不存在的变量
      delete no;  //false

    })();

    (function(){
      "use strict";   //严格模式
      var a = 10;
      var fun = function(){console.log("fun called");};
      var o = Object.defineProperty({}, "name", {
        value: "Bob"
      });   //默认即不可配置
      //delete a;   //SyntaxError: Delete of an unqualified identifier in strict mode.
      console.log(a);

      delete fun;  //SyntaxError: Delete of an unqualified identifier in strict mode.
      fun();

      delete o.name;  //SyntaxError: Delete of an unqualified identifier in strict mode.
      console.log(o.name);

      //删除一个不存在的变量
      delete no;  //SyntaxError: Delete of an unqualified identifier in strict mode.

    })();
复制代码
8,在严格模式下,arguments和eval是关键字,不能被修改
    (function(){
      //非严格模式
      eval = 10;
      eval("console.log('hello');");  //TypeError: eval is not a function

      (function(){
        arguments = 20;
        console.log(arguments);   //20
      }());

    })();

    (function(){
      "use strict";   //严格模式
      eval = 10;  //SyntaxError: Unexpected eval or arguments in strict mode
      eval("console.log('hello');");

      (function(){
      arguments =20;  //SyntaxError: Unexpected eval or arguments in strict mode
        console.log(arguments);
      }());

    })();
复制代码
9,在严格模式下,不可以用8进制
(function(){
      //非严格模式
      console.log(070);  //56 (因浏览器而异)
    })();

    (function(){
      "use strict";   //严格模式
      console.log(070);  //SyntaxError: Octal literals are not allowed in strict mode.
    })();
复制代码
10,在严格模式下,函数的形参不可以同名
    (function(){
      //非严格模式
      var one = 1;
      var two = 2;
      fun(one, two);   //2
      function fun(a,a){
        console.log(a);
      }
    })();

    (function(){
      "use strict";   //严格模式
      var one = 1;
      var two = 2;
      fun(one, two);
      function fun(a,a){  //SyntaxError: Duplicate parameter name not allowed in this context
        console.log(a);
      }
    })();
复制代码
11,在严格模式下,不可以使用caller和arguments的属性,会报错
(function(){
  //非严格模式
  A();

  function A(){
    B();
  }
  function B(){
    console.log(B.caller);   //function A(){ B(); }
    console.log(arguments.callee);    //function B(){ console.log(B.caller); console.log(arguments.callee); }
  }
})();

(function(){
  "use strict";   //严格模式
  A();

  function A(){
    B();
  }
  function B(){
    console.log(B.caller);   //TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.
    console.log(arguments.callee);    //TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
  }
复制代码

以上就是我目前接触到的ES6新增特性.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值