横冲直撞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这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

 

 

 

posted on 2020-04-03 22:12  Nicholas--  阅读(267)  评论(0编辑  收藏  举报

导航