【有书共读08】JS核心技术开发解密读书笔记10

JavaScript核心技术开发解密(第九、十章)读书笔记
第九章上次写笔记的童鞋写完9.1节,9.2-9.5节请参考我组Charles童鞋的博客,这里不在记录,本文主要讲解第十章ES6(上)的内容。本文关于ES6的讲解比较简单,如有兴趣还请阅读阮一峰大佬的ECMAScript
6入门

第十章 ES6与模块化

1. 常用语法知识
let/const

在ES5中,使用var来声明一个变量。在ES6中,新的变量声明方式带来了一些不一样的特性,其中最重要的就是具备了块级作用域并且不再有变量提升(这很重要)。
下面通过一个简单的例子来说明。

// ES5
console.log(a); // undefined
var a = 20;

// ES6
console.log(a); // Uncaught ReferenceError: a is not defined
let a = 20;

ES5存在变量提升,其实ES6也存在,但是并不会给这个变量赋值为undefined。也就是说,虽然声明提前了,但是该变量并没有任何引用,所以上例才会报ReferenceError。
由于不会默认赋值undefined,加上let/const存在自己的作用于,因此会出现一个叫作暂时性死区的现象。
因此在编写ES6代码中要注意,尽量将申明主动放置在代码的前面。
要想使用ES6,就需要全面使用let/const来替换之前非常常用的var,那么什么时候用let,什么时候用const呢?

一般来说,声明一个引用可以被改变的变量时用let,声明一个引用不能被改变的变量时用const。

例如:

let a = 20;
a = 30;
a = 40;
console.log(a); // 40

const PI = 3.1415;
const MAX_LENGTH = 100;

PI = 3; // Uncaught TypeError: Assignment to constant variable

除此之外,当声明一个引用类型的数据时,也会使用const。尽管可能会改变该数据的值,但是必须保持它的引用不变。

const a = [];
a.push(1);
console.log(a); // [1]

const b = {};
b.max = 20;
b.min = 0;
console.log(b); // {max: 20, min: 0}
箭头函数

与function相比,箭头函数是一个用起来更加舒服的语法。

// ES5
var fn = function (a, b) {
  return a + b;
}

// ES6
const fn = (a, b) => a + b;

// ES5
var foo = function () {
  var a = 20;
  var b = 30;
  return a + b;
}

// ES6
const foo = () => {
  const a = 20;
  const b = 30;
  return a + b;
}

需要注意,箭头函数只能替换函数表达式,即使用var/let/const声明的函数。而直接使用function声明的函数是不能使用箭头函数替换的。

箭头函数中的this,就是声明函数时所处上下文中的this,它不会被其他方式所改变。

// ES5
var name = 'Tom';
var getName = function () {
  console.log(this.name);
}
var person = {
  name: 'Alex',
  getName: getName
}
var other = {
  name: 'Joe'
}
getName(); // Tom,默认绑定,this指向window
person.getName(); // Alex,由person调用,this指向person
getName.call(other); // Joe,显示绑定,通过call使this指向other

// ES6
var name = 'Tom';
var getName = () => {
  console.log(this.name);
}
var person = {
  name: 'Alex',
  getName: getName
}
var other = {
  name: 'Joe'
}
getName(); // Tom
person.getName(); // Tom
getName.call(other); // Tom

除此之外,arguments还有一个需要大家注意的地方,即在箭头函数中,没有arguments对象。

// ES5
var add = function (a, b) {
  console.log(arguments);
  return a + b;
}
add(1, 2); // Arguments(2) [1, 2, callee: f, Symbol(Symbol.iterator): f]

// ES6
var add = (a, b) => {
  console.log(arguments);
  return a + b;
}
add(1, 2); // Uncaught ReferenceError: arguments is not defined
2. 模板字符串

模板字符串是为了解决传统字符串拼接不便利而出现的。

// ES5
var a = 20;
var b = 30;
var string = a + "+" + b + "=" + (a + b);

// ES6
const a = 20;
const b = 30;
const string = `${a} + ${b} = ${a + b}`;

模板字符串使用反引号`将整个字符串包裹起来,变量或表达式则使用${}来包裹。
除了能够在字符串中嵌入变量,还可以用来定义多行字符串,其中所有的空格、缩进、换行都会被保留下来。

var elemString = `<div>
  <p>I like brother black.</p>
  <p>I am sorry to lose you. ${word}</p>
</div>`

如果是用传统的+拼接这段字符串,则会非常麻烦(各种转义)。
${}中可以放入一个变量、表达式,甚至一个函数。

const hello = 'hello';
let message = `${hello}, world!`;

const a = 20;
const b = 30;
let result = `the result is: ${a + b}`;

let fn = () => {
  const result = `you are the best`;
  return result;
}
let str = `he said: ${fn()}`;
3. 解析结构(解构赋值)

解构赋值是一种从对象或者数组中取得值的一种全新的写法,只需通过一个简单的例子就能立刻明白是怎么回事(实际开发用的很多)。

// 假设存在这样一个json数据
var tom = {
  name: 'Tom',
  age: 20,
  gender: 1,
  job: 'student'
}

// ES5
var name = tom.name;
var age = tom.age;
var gender = tom.gender;
var job = tom.job;

// ES6
const {name, age, gender, job} = tom;

可以看到ES6解构赋值比传统赋值方便了很多,我们还可以给变量指定默认值或者重命名。

const {name = 'Jake', stature = '170'} = tom;
console.log(name); // Tom,如果数据中找到name,则变量的值与数据中相等
console.log(stature); // 170,如果数据中找不到stature,则使用默认值

const {gender: t, job} = tom;
console.log(gender); // Uncaught ReferenceError: gender is not defined
console.log(t); // 1,重命名后gender将无法访问

我们还可以利用解构赋值获取嵌套数据中的值。

const peoples = {
  counts: 100,
  detail: {
    tom: {
      name: 'Tom',
      age: 20,
      gender: 1,
      job: 'student'
    }
  }
}
// 获取tom
const {detail: {tom}} = peoples;
// 获取tom的age与gender
const {detail: {tom: {age, gender}}} = peoples;

此外,数组也有自己的解构赋值。当然,写法与对象的解构赋值略有不同。

const arr = [1, 2, 3];
const [a, b, c] = arr;

// 等价于
const a = arr[0];
const b = arr[1];
const c = arr[2];

与对象不同的是,数组中变量和值得关系与索引是一一对应的,这是一个有序的对应关系,而对象则是根据键值对一一对应的,这是一个无序的对应关系系。因此在实践中,对象的解构赋值使用的更加频繁与便利。

4. 展开运算符

在ES6中,使用...来表示展开运算符,它可以展开数组/对象。

// 首先声明一个数组
const arr1 = [1, 2, 3];
// 其次声明另一个数组,我们希望新数组中包含数组arr1的所有元素
const arr2 = [...arr1, 4, 5, 6];
console.log(arr2); // [1, 2, 3, 4, 5, 6]

当然,展开对象也可以得到类似的结果。

const object1 = {
  a: 1,
  b: 2,
  c: 3
}
const object2 = {
  ...object1,
  d: 4,
  e: 5,
  f: 6
}
console.log(object2); {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}

在解构赋值中,也常常使用展开运算符。

const tom = {
  name: 'Tom',
  age: 20,
  gender: 1,
  job: 'student'
}
const {name, ...others} = tom;
console.log(others); // {age: 20, gender: 1, job: 'student'}
//react中使用解构传递数据
var prop={
  size: 20,
  src: xxx,
  mode: 1
}

展开运算符还可以运用在函数参数中,放置于函数参数的最后一个参数(且只能放置在最后,具体原因参考阮一峰ECMAScript6入门),表示不定参。

const add = (a, b, ...more) => {
  return more.reduce((m, n) => m + n) + a + n;
}
console.log(add(1, 23, 1, 2, 3, 4, 5)); // 39

喜欢本文的小伙伴请关注我的简书BeLLESS。最后再次感谢Charles,Cici童鞋以及牛客组织的有书共读活动,我们下期将为大家介绍剩下的关于ES6的知识,下期再见。

#读书笔记##笔记#
全部评论

相关推荐

预计下个星期就能开奖吧,哪位老哥来给个准信
华孝子爱信等:对接人上周说的是这周
点赞 评论 收藏
分享
点赞 评论 收藏
分享
10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务