学习 Vue.js 需要掌握的 es6 (1)

针对之学习 Vue 用到的 es6 特性,做下简单总结。

var、let 与 const

var 与 let

es6 之前,JavaScript 并没有块级作用域,所谓的块,就是大括号里面的语句所组成的代码块,比如

function fire(bool) {
    if (bool) {
        var foo = "bar";
    }
    console.log(foo);
}

fire(true); //=> bar

虽然变量 foo 位于 if 语句的代码块中,但是 JavaScript 并没有块级作用域的概念,因此被添加到了当前的执行环境 - 即函数中,在函数内都可以访问到。

另外一个令人困惑的地方是变量提升:

function fire(bool) {
    if (bool) {
        var foo = "bar";
    } else {
        console.log(foo);
    }
}
fire(false); //=> undefined

我们都知道,直接访问一个未定义的变量,会报错:

console.log(nope); //=> Uncaught ReferenceError: nope is not defined

但是在上述的例子中,会返回 undefined。也就是说,变量的定义被提升到了作用域的顶部,等价于:

function fire(bool) {
    var foo;
    if (bool) {
           foo = "bar";
    } else {
        console.log(foo);
    }
}
fire(false);

而在 JavaScript 中,声明但是未赋值的变量会被赋值为 undefined,因此,结果输出 undefined

为了解决上述问题,引入了 let 关键字,let 定义的变量。

首先,let 定义的变量只在代码块内有效:

function fire(bool) {
    if (bool) {
        let foo = "bar";
    }
    console.log(foo);
}

fire(true); //=> Uncaught ReferenceError: foo is not defined

其次, let 定义的变量不存在变量提升:

function fire(bool) {
    if (bool) {
        let foo = "bar";
    } else {
        console.log(foo);
    }
}
fire(false); //=> Uncaught ReferenceError: foo is not defined

因此,使用 let,上述问题完全解决,这也告诉了我们,应当尽可能的避免用 var,用 let 来代替,除非你需要用到变量提升。

const

const 与 let 的基本用法相同,定义的变量都具有块级作用域,也不会发生变量提升。不同的地方在于,const 定义的变量,只能赋值一次。

对于基本类型来说,需要通过赋值来改变其值,因此 const 定义之后就相当于无法改变:

const a = 1;
a = 2;  // Uncaught TypeError: Assignment to constant variable.
++a;  // Uncaught TypeError: Assignment to constant variable.

对于数组和对象来说,值是可以改变的:

const arr  = ["a","b","c"];
arr.push("d");
arr.pop();

那么什么时候使用 const 呢? 在一些不需要重复赋值的场合可以用:

const provinces = [];
const months = [];

总而言之,多用 let 和 const,少用 var 。

箭头函数

在 Vue 中,使用箭头函数的最大好处就是可以让 this 指向 Vue 实例:

var vm = new Vue({
    el:'#root',
    data:{
        tasks:[]
    },
    mounted(){
        axios.get('/tasks')
        .then(function (response) {
            vm.tasks = response.data;
        })
    }
});

由于回调函数的 this 指向全局对象 window,因此,我们需要通过 vm 来访问实例的方法,如果使用箭头函数,则可以写成:

new Vue({
    el:'#root',
    data:{
        tasks:[]
    },
    mounted(){
           axios.get('/tasks')
            .then(response => this.tasks = response.data);
    }
});

箭头函数的 this 对象始终指向定义函数时所在的对象,相当于:

var vm = new Vue({
    el:'#root',
    data:{
        tasks:[]
    },
    mounted(){
        var that = this;
        axios.get('/tasks')
        .then(function (response) {
            that.tasks = response.data;
        })
    }
});

模板字符串

模板字符串为 Vue 的组件模板定义带来了巨大的便利,在此之前,需要这样定义一个模板:

let template = '<div class="container"><p>Foo</p></div>';

如果要写成多行,可以用反斜杠:

let template = '<div class="container">\
                    <p>Foo</p>\
                </div>';

或者使用数组形式:

let template = [
    '<div class="container">',
    '<p>Foo</p>',
    '</div>'
].join('');

如果要嵌入变量,可以写成:

let name = "jack";
let template = `<div class="container"><p>` + name + '</p></div>';

而使用模板字符串,则可以方便的在多行里面编写模板:

let template = `
    <div class="container">
        <p>Foo</p>
    </div>
`

由于模板字符串的空格和换行会被保留,为了不让首行多出换行符,可以写成:

let template = `<div class="container">
                            <p>Foo</p>
                        </div>
                    `

或者使用 trim() 方法从字符串中移除 前导 空格、尾随空格和行终止符。

let template = `
    <div class="container">
        <p>Foo</p>
    </div>
`.trim();

模板字符串嵌入变量或者表达式的方式也很简单:

let name = "jack";
let template = `
    <div class="container">
        <p>${name} is {100 + 100}</p>
    </div>
`.trim();

默认参数

在 es6 之前,JavaScript 不能像 PHP 那样支持默认参数,因此需要自己手动定义:

function  takeDiscount(price, discount){
    discount  = discount || 0.9;
    return price * discount;
}
takeDiscount(100);

es6 则允许定义默认参数

function takeDiscount(price, discount = 0.9){
    return price * discount;
}
takeDiscount(100);

甚至可以以函数形式传递参数:

function getDiscount(){
    return 0.9;
}

function takeDiscount(price, discount = getDiscount()){
    return price * discount;
}
takeDiscount(100);

rest 参数

先从函数的参数传递说起:

function sum(a,b,c){
    let total = a + b + c;
    return total;
}
sum(1, 2, 3);

在 JavaScript 中,函数参数实际上以数组的方式进行传递,参数会被保存在 arguments 数组中,因此上例等价于:

function sum(){
    let total = arguments[0] + arguments[1] + arguments[2];
    return total;
}
sum(1, 2, 3);

不过 arguments 不单单包括参数,也包括了其他东西,因此没法直接用数组函数来操作 arguments。如果要扩展成任意多个数值相加,可以使用循环:

function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total = total + arguments[i];
    }
    return total;
}
sum(1, 2, 3, 4, 6);

es6 则提供了 rest 参数来访问多余变量,上例等价于:

function sum(...num) {
    let total = 0;
    for (let i = 0; i < num.length; i++) {
        total = total + num[i];
    }
    return total;
}
sum(1, 2, 3, 4, 6);

可以以变量形式进行传递:

function sum(...num) {
    let total = 0;
    for (let i = 0; i < num.length; i++) {
        total = total + num[i];
    }
    return total;
}
let nums = [1, 2, 3, 4, 6];
sum(...nums);

在函数中体内,num 就是单纯由参数构成的数组,因此可以用数组函数 reduce 来实现同样的功能:

function sum(...num) {
    return num.reduce( (preval, curval) => {
        return preval + curval;
    })
}
sum(1, 2, 3, 4, 6);

... 还可以与其他参数结合使用,只需要将其他参数放在前面即可:

function sum(total = 0, ...num) {
    return total + num.reduce( (preval, curval) => {
        return preval + curval;
    });
}

let nums = [1,2,3,4];
sum(100, ...nums);

对象的简写

函数的简写

函数的简写,在 Vue 中会用到:

Vue({
   el: '#root',
   data:data,
   methods: {
       addName: function() {
           vm.names.push(vm.newName);
           vm.newName = "";
       }
   }
});

可以简写为:

new Vue({
   el: '#root',
   data:data,
   methods: {
       addName() {
           vm.names.push(vm.newName);
           vm.newName = "";
       }
   }
});

在组件中频繁用到:

Vue.component('example',{
    data(){
        return {

        };
    }
});

属性的简写

let data = {
        message: "你好,Vue"
    };

var vm = new Vue({
    el: '#root',
    data:data
})

可以简写成:

let data = {
        message: "你好,Vue"
    };

var vm = new Vue({
    el: '#root',
    data
})

也就是说,可以直接在对象中直接写入变量,当函数的返回值为对象时候,使用简写方式更加简洁直观:

function getPerson(){
    let name = 'Jack';
    let age = 10;

    return {name, age};
    // 等价于
    // return {
    //     name : name,
    //     age : age
    // }

}
getPerson();

解构赋值

解构赋值可以方便的取到对象的可遍历属性:

let person = {
    firstname : "steve",
    lastname : "curry",
    age : 29,
    sex : "man"
};

let {firstname, lastname} = person;
console.log(firstname, lastname);

// 等价于
// let firstname = person.firstname;
// let lastname = person.lastname;

可以将其用于函数传参中:

function greet({firstname, lastname}) {
    console.log(`hello,${firstname}.${lastname}!`);
};
greet({
    firstname: 'steve',
    lastname: 'curry'
});

 

评论

0条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注