zoukankan      html  css  js  c++  java
  • 横冲直撞vue(第一篇):常用的ES6语法

     

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。也就是说,ES6就是ES2015。虽然目前并不是所有浏览器都能兼容ES6全部特性,但越来越多的程序员在实际项目当中已经开始使用ES6了。今天就来总结一下在工作中es6常用的属性方法。

    一、let、const与 block 作用域

     

    block块级作用域

     

    ES6引入了块级作用域,块内部定义的变量,在外部是不可以访问的.

    例子1

    if(true){
        // var flag = 123;
        let flag = 123;
    }
    ​
    // console.log(flag);
    //当使用var声明时可以打印,
    // 但使用let声明就不能打印了,{}相当于一个块级作用域
    ​
    

      

    直接使用{}也可以形成一个块级作用域

    {
        // 这里是块级作用域
        let flag = 111;
        console.log(flag);
    }
    console.log(flag);//这里会报错,不能获取到块级作用域里声明的变量
    ​
    

      


    在块级作用域内部,变量也是只能先声明再使用

    if(true){
        console.log(flag);
        let flag = 123;
    }
     
    

      

    let

    ES6新增了let命令,用来生命变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

    for (let i = 0; i < 10; i++) {
     
     }
        console.log(i) //ReferenceError: i is not defined<br>
    for(var i=0;i<10;i++){
    ​
    }
    console.log(i) //10
    

      

    上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。let具有块级作用域的。var不存在块级作用域问题,具有全局变量提示的问题存在.

     

    let声明的变量不允许重复(在同一个作用域内)

    let flag = 123;
    let flag = 456;
    console.log(flag);//会报错
    ​
    

      

    let声明的变量不存在预解析

    console.log(flag);
    var flag = 123;
    let flag = 123; //不再预解析,直接报错
    ​
    

      

     

    for循环中的块级作用域使用

    for (var i = 0; i < 3; i++) {
        console.log(i);
    }
    console.log(i); //这里不会有问题,i变成了3,可以打印,var的作用域是全局的,所以不会报错
    ​
    

      

    而使用let

    for (let i = 0; i < 3; i++) {
        // for循环括号中声明的变量只能在循环体中使用
        console.log(i);
    }
    console.log(i);//会报错,无法获取i
    ​
    

      

     

     

    const

    const声明一个只读的常量,一旦声明,常量的值就不能改变。

    const a = 2;
        a = 20;
    console.log(a)  //TypeError: Assignment to constant variable.
    上面代码表明改变常量的值会报错。
    

      

    const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

    const a;
    console.log(a)
    

      

    上面代码表示,对于const来说,只声明不赋值,就会报错。

     

    let与const

     1.都不能重复声明

     2.都存在块级作用域问题

    3.只在声明所在的块级作用域内有效。

     

    二、模板字符串

    模板字符串就是一种字符串的新的表现形式

    (1)基本用法

    let s1 = ` hello `
    let s2 = ' hello '
    

      

    (2)字符串和变量拼接

     

    let s3 =" a " + s1 + " b " + s2;
    let s4 = ` a ${s1} b ${s2}`;  
    

      

     

    (3)字符串换行

    var box =`<div>
                <p>
                  <span>123</span>
                </p>
                <p>${a1}</p>
             </div>`;
    

      

    模板字符串的出现,极大的改变传统字符串的拼接方法,减少代码出现错误的几率。提高开发效率

     

    三、箭头函数(Arrow Functions)

    ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体:

    基本用法

    //匿名函数
        div.onclick=function(){
            console.log("你好")
        }
        //箭头函数
        div.onclick=()=>{
            console.log("你好")
        }
    

      

     

    有一个参数的箭头函数

    var fn=(a)=>{
            console.log("abc");
        }
    //等价于:
    var fn=a=>{
            console.log("abc");
        }
    

      

    有2个及更多参数的箭头函数

    var f=(a,b,c)=>{
            console.log("abc")
        }
    

      

    //无形参
    var f = () => 5;
    // 等同于
    var f = function () { return 5 };
    ​
    //多个形参
    var sum = (num1, num2) => num1 + num2;
    // 等同于
    var sum = function(num1, num2) {
      return num1 + num2;
    };
    

      

     

    箭头函数有几个使用注意点。

    1、函数体内的this对象,就是使用时所在的对象。

    // ES3、ES5中普通函数
    var name = '张三';
    var person = {
        name:'nicholas',
           age:18,  
        fav:function(){
            console.log(this);
            console.log(this.name)
        }
    };
    person.fav();
    

      

    打印结果为

     

     

    此时this指向的是使用它的对象,也就是person对象,即调用它的对象。

     

    而使用箭头函数

    //使用箭头函数
    var person = {
        name: 'nicholas',
        age: 18,
        fav: () => {
            // 当前this对象(window)
            console.log(this);
            console.log('this');
        }
    };
    person.fav();
    

      

    打印结果

     

     

    此时因为箭头函数是指向全局的,即window对象

    箭头函数的this永远指向其父作用域,任何方法都改变不了,包括call,apply,bind。 普通函数的this指向调用它的那个对象。

    Javascript定时器中的this指向

    var name = 'my name is window';
    var obj = {
        name: 'my name is obj',
        fn: function () {
            var timer = null;
            clearInterval(timer);
            timer = setInterval(function () {
                console.log(this.name);  //my name is window
            }, 1000)
        }
    }
    

      

    在这里,从this.name可以看出this的指向是window。

    如果没有特殊指向,setInterval和setTimeout的回调函数中this的指向都是window。这是因为JS的定时器方法是定义在window下的。但是平时很多场景下,都需要修改this的指向。这里总结了几种:

    (1)最常用的方法:在外部函数中将this存为一个变量,回调函数中使用该变量,而不是直接使用this。

     

     var name = 'my name is window';
     var obj = {
         name: 'my name is obj',
         fn: function () {
              var that = this;
              var timer = null;
             clearInterval(timer);
              timer = setInterval(function () {
                 console.log(that.name);   //my name is obj
             }, 1000)
         }
     }
    

      

     

     

    在fn中加了var that = this; 回调函数中使用that代替this即可。这种方法最常见,使用也最广泛。

    (2)使用es6的箭头函数:箭头函数的最大作用就是this指向。

    var name = 'my name is window';
    var obj = {
        name: 'my name is obj',
        fn: function () {
            var timer = null;
            clearInterval(timer);
            timer = setInterval(() => {
                console.log(this.name);  //my name is obj
            }, 1000)
        }
    }
    

      

     

    箭头函数没有自己的this,它的this继承自外部函数的作用域。所以,在该例中,定时器回调函数中的this,是继承了fn的this。当然箭头函数也有兼容问题,要是兼容低版本ie,需要使用babel编译,并且引入es5-shim.js才可以。

     

     

    2、不可以使用arguments对象,该对象在函数体内不存在。

     

    let foo = (a,b) => {
        console.log(a,b);
        // console.log(arguments);//这种方式获取不到实参列表
    };
    foo(123,456);
    ​
    

      

     

    四、对象的简洁表示法

     

    属性简写

    ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

    const foo = 'bar';
    const baz = {foo};
    baz // {foo: "bar"}
    ​
    // 等同于
    const baz = {foo: foo};
    

      

    上面代码中,变量foo直接写在大括号里面。这时,属性名就是变量名, 属性值就是变量值。下面是另一个例子。

    function f(x, y) {
      return {x, y};
    }
    ​
    // 等同于
    ​
    function f(x, y) {
      return {x: x, y: y};
    }
    ​
    f(1, 2) // Object {x: 1, y: 2}
    

      

    方法简写

    const o = {
      method() {
        return "Hello!";
      }
    };
    ​
    // 等同于
    ​
    const o = {
      method: function() {
        return "Hello!";
      }
    };
    

      

    例子2

    let birth = '2000/01/01';
    ​
    const Person = {
    ​
      name: '张三',
    ​
      //等同于birth: birth
      birth,
    ​
      // 等同于hello: function ()...
      hello() { console.log('我的名字是', this.name); }
    ​
    };
    

      

    例子3

    function getPoint() {
      const x = 1;
      const y = 10;
      return {x, y};
    }
    ​
    getPoint()
    // {x:1, y:10}
    

      

    五、es6中的解构赋值

    ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

    变量的解构赋值

    以前,为变量赋值,只能直接指定值。

    let a = 1;
    let b = 2;
    let c = 3;
    

      

    ES6 允许写成下面这样。

    let [a, b, c] = [1, 2, 3];
    

      

    上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。

    例子

    let [a,b,c] = [,123,];  //与前面的数组是一一对应的关系,没有值就是undefined
    console.log(a,b,c)  //输出:undefined 123 undefined
    ​
    ​
    let [a=111,b,c] = [,123,];//可以在前面设置默认值
    console.log(a,b,c);  //输出:111 123 undefined
    ​
    

      

    对象的解构赋值

    解构不仅可以用于数组,还可以用于对象。

    let {foo,bar} = {foo : 'hello',bar : 'hi'};
    let {foo1,bar1} = {bar1 : 'hi',foo1 : 'hello'};//改变key的顺序无影响
    console.log(foo,bar);//打印的value
    console.log(foo1,bar1);//打印的value
    

      


    对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    变量没有对应的同名属性,导致取不到值,最后等于undefined

    let {foo} = {bar: 'baz'};
    foo // undefined
    

      

    变量没有对应的同名属性,导致取不到值,最后等于undefined

    对象的解构赋值是下面形式的简写

    let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
    

      

    也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

    对象属性别名(如果有了别名,那么原来的名字就无效了)

    let {foo:abc,bar} = {bar : 'hi',foo : 'nihao'};
    //给foo这个key设置别名,可以用别名,但原来的key就不能用了
    console.log(abc,bar);
    console.log(foo,bar);//会报错
    如果解构失败,变量的值等于undefined。
    

      

    对象的解构赋值指定默认值

    let {foo:abc='hello',bar} = {bar : 'hi'};
    console.log(abc,bar);
    ​
    

      

     

    六、Class 的基本语法

     

    JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。

    function Point(x, y) {
      this.x = x;
      this.y = y;
    }
    ​
    Point.prototype.toString = function () {
      return '(' + this.x + ', ' + this.y + ')';
    };
    ​
    var p = new Point(1, 2);
    

      

    上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。

    ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

    基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样

    class Animal{
                
                // 构造器  当你创建实例之后 constructor()方法会立刻调用 通常这个方法初始化对象的属性
                constructor(name,age){
                    this.name = name;
                    this.age = age;
                }
                showName(){
                    console.log(this.name);
                }
            }
            var a2 = new Animal('点点',3);
    

      

    上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5 的构造函数Animal,对应 ES6 的Animal类的构造方法。

    Animal类除了构造方法,还定义了一个showName方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

     

     

     

  • 相关阅读:
    苏教版国标本小学语文第一册汉字笔画
    C++ preprocessor __VA_ARGS__ number of arguments
    The Aggregate Magic Algorithms
    USB Mass Storage大容量存储的基本知识
    【转】驱动和应用层的三种通信方式
    Do You Actually Know What *P++ Does In C?
    Repeat Macro Cloak
    A SCSI command code quick reference
    USB device layout, descriptors, interface alternate setting
    RTOS Semaphore Services
  • 原文地址:https://www.cnblogs.com/Nicholas0707/p/12629289.html
Copyright © 2011-2022 走看看