Skip to content

ES6部分方法点评(一) #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Array-Huang opened this issue Nov 15, 2019 · 0 comments
Open

ES6部分方法点评(一) #11

Array-Huang opened this issue Nov 15, 2019 · 0 comments

Comments

@Array-Huang
Copy link
Owner

一直以来,我对ES6都不甚感兴趣,一是因为在生产环境中使用ES5已是处处碰壁,其次则是只当这ES6是语法糖不曾重视。
只是最近学习react生态,用起babel来转换jsx之余,也不免碰到诸多用上ES6的教程、案例,因此便稍作学习。这一学习,便觉得这语法糖实在是甜,忍不住尝鲜,于是记录部分自觉对自己有用的方法在此。

箭头函数(Arrow Functions)

箭头函数是一个典型的语法糖,即创造了一种新语法来简化javascript中函数的写法:

// ES5
var selected = allJobs.filter(function (job) {
  return job.isSelected();
});
// ES6
var selected = allJobs.filter(job => job.isSelected());

上面这是函数只有一个形参的情况,下面列举函数有多个形参的情况:

// ES5
var total = values.reduce(function (a, b) {
  return a + b;
}, 0);
// ES6
var total = values.reduce((a, b) => a + b, 0);

语法大体是这样:([函数的形参,多个参数则以逗号分隔]) => [函数返回的值/表达式]
另外,箭头函数也可以使用{}来引入函数块语句,不过这样的话其实就只是简写了function这一个单词了,意义不是很大,下面放个例子:

// ES5
$("#confetti-btn").click(function (event) {
  playTrumpet();
  fireConfettiCannon();
});
// ES6
$("#confetti-btn").click(event => {
  playTrumpet();
  fireConfettiCannon();
});

对我来说,简写并不吸引我,吸引我的,是箭头函数的一个重要特性:箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。


2016-05-31修改: @n͛i͛g͛h͛t͛i͛r͛e͛同学指出

arrow function 不是“没有自己的 this”,而是绑定了定义时的 context;这一特性等价于以前的
Function.prototype.bind

我翻查了一下MDN,里面是这么写的:

箭头函数则会捕获其所在上下文的 this 值,作为自己的 this 值。

因此,@n͛i͛g͛h͛t͛i͛r͛e͛同学的说法是有理的。


这在编写回调函数的时候就非常好用了,我们再也不需要利用闭包来保存this了(尤其是,很容易忘记保存this而直接在回调函数里用了this):
{
add: function(piece) {},
...
addAll: function addAll(pieces) {
var self = this;
_.each(pieces, function (piece) {
self.add(piece);
});
},
...
}

// ES6
{
  add: function(piece) {},
  ...
  addAll: function addAll(pieces) {
    _.each(pieces, piece => this.add(piece));
  },
  ...
}

let

自ES6中let的出现,javascript终于迎来了块级作用域({}、for、if)。


2016-05-31修改:
此处表达有误,应为:自ES6,javascript开始拥有块级作用域,而let则是配合块级作用域,作为替代var的一个语法定义。


有了块级作用域,再也不用担心临时变量污染到外层的变量了:

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

const

const是用来定义常量的,一旦定义了就不可修改(一修改就报错)。用途嘛,也比较单一,就是定义一下配置项什么的,免得被团队里的愣头青写的代码给瞎改了。


2016-05-31修改 @n͛i͛g͛h͛t͛i͛r͛e͛同学提出一个“命名绑定”的概念,并举出一个相应的例子:

const config = {};
config.env = 'development';  // 这不会报错

config = {};  // 这才会报错

请恕我才疏学浅,尚不能理解“命名绑定”呀、函数式编程之类的。我对上面这个例子的理解是,config只是一个object的引用,无论这个object本身怎么变化,只要config这个变量的“指向”没变化,那就不会报错。


destructuring

destructuring是解构的意思,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。来两个例子看看大家就明白了。

'use strict';

// 数组的解构赋值
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3

// 对象的解构赋值
var { foo, bar } = { foo: "aaa", bar: "bbb" };
console.log(foo);   // "aaa"
console.log(bar );  // "bbb"

// 字符串的解构赋值
const [a, b, c, d, e] = 'hello';
console.log(a + b + c + e); // 'hello'

跟箭头函数一样,也是个语法糖,那这是用在什么地方呢?请不要着急,听我细细道来:
在我们封装函数的时候,如果形参较多,为了使用者不需要按顺序来传入参数,往往用一个object来承载所有的参数,例如这样:

// 二逼青年写法
function study(id, name, sex, grade, nickname, age, address) {
    console.log(id);
    console.log(name);
    console.log(sex);
    console.log(grade);
    console.log(nickname);
    console.log(age);
    console.log(address);
}
// 正常青年写法
function study(params) {
    console.log(params.id);
    console.log(params.name);
    console.log(params.sex);
    console.log(params.grade);
    console.log(params.nickname);
    console.log(params.age);
    console.log(params.address);
}

这种做法,虽说使用者是方便了,但写函数的人却麻烦了,每次用参数都要带上params.,或者再写个var id = params.id来让后续的使用方便一些。
然而,有了destructuring后,我们有了更方便的写法:
function study({id, name, sex, grade, nickname, age, address}) {
console.log(id);
console.log(name);
console.log(sex);
console.log(grade);
console.log(nickname);
console.log(age);
console.log(address);
}
study({
id: 1,
name: '林有德',
sex: '男',
grade: '一年级',
nickname: '布莱德',
age: 12,
address: '木马号'
});

这样一来,使用者用起来很方便,而函数内部又直接解构赋值到各变量上,用起来也方便多了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant