ES6入门

知识点:let const 变量声明

              数组解构赋值  变量交换值 函数结构赋值

             字符模板  Unincode编码  模板字符串应用场景及方法

 

 

 

1.对变量的新增

let 只能声明一次 

1).它不可以变量提升

2).可以重复赋值,它仅限于在代码块中

const 只能声明一次,并且只能赋值一次

1).同let一样不可以变量提升仅限于代码块中

列:

for (let i = 0; i < 10; i++) {
  // ...
}

2.变量的解构赋值

1)。基本赋值

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

如果解构不成功则为undefined
比如:
let [a,b]=[1] // 1,undefined

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

2).错误写法

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

3).对于 new Set解构

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

4).默认值

//解构赋值允许指定默认值。

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'


注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null

上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。



如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

function f() {
  console.log('aaa');
}

let [x = f()] = [1];

上面代码中,因为x能取到值,所以函数f根本不会执行。上面的代码其实等价于下面的代码。



默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined

上面最后一个表达式之所以会报错,是因为x用y做默认值时,y还没有声明。

3.对象的解构赋值

1).

简介 § 

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

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



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

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

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined   //如果解构失败,变量的值等于undefined。



对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello

上面代码的例一将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。例二将console.log赋值到log变量。


如果变量名与属性名不一致,必须写成下面这样。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'



与数组一样,解构也可以用于嵌套结构的对象。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"



注意,这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]


下面是另一个例子。

const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};

let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}



函数的扩展
数组的扩展
对象的扩展
对象的新增方法
Symbol
Set 和 Map 数据结构
Proxy
Reflect
Promise 对象
Iterator 和 for...of 循环
Generator 函数的语法
Generator 函数的异步应用
async 函数
Class 的基本语法
Class 的继承
Module 的语法
Module 的加载实现
编程风格
读懂规格
ArrayBuffer
最新提案
Decorator
参考链接
其他
源码
修订历史
反馈意见
变量的解构赋值
数组的解构赋值
对象的解构赋值
字符串的解构赋值
数值和布尔值的解构赋值
函数参数的解构赋值
圆括号问题
用途
数组的解构赋值
基本用法
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

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

let a = 1;
let b = 2;
let c = 3;
ES6 允许写成下面这样。

let [a, b, c] = [1, 2, 3];
上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
如果解构不成功,变量的值就等于undefined。

let [foo] = [];
let [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。

另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
上面两个例子,都属于不完全解构,但是可以成功。

如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
上面的语句都会报错,因为等号右边的值,要么转为对象以后不具备 Iterator 接口(前五个表达式),要么本身就不具备 Iterator 接口(最后一个表达式)。

对于 Set 结构,也可以使用数组的解构赋值。

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"
事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
上面代码中,fibs是一个 Generator 函数(参见《Generator 函数》一章),原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。

默认值
解构赋值允许指定默认值。

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null
上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

function f() {
  console.log('aaa');
}

let [x = f()] = [1];
上面代码中,因为x能取到值,所以函数f根本不会执行。上面的代码其实等价于下面的代码。

let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined
上面最后一个表达式之所以会报错,是因为x用y做默认值时,y还没有声明。

对象的解构赋值
简介
解构不仅可以用于数组,还可以用于对象。

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

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

let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于undefined。

如果解构失败,变量的值等于undefined。

let {foo} = {bar: 'baz'};
foo // undefined
上面代码中,等号右边的对象没有foo属性,所以变量foo取不到值,所以等于undefined。

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello
上面代码的例一将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。例二将console.log赋值到log变量。

如果变量名与属性名不一致,必须写成下面这样。

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

let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
这实际上说明,对象的解构赋值是下面形式的简写(参见《对象的扩展》一章)。

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined
上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。

与数组一样,解构也可以用于嵌套结构的对象。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
注意,这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
下面是另一个例子。

const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};

let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}
上面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。

下面是嵌套赋值的例子。

let obj = {};
let arr = [];

({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });

obj // {prop:123}
arr // [true]

 

2).错误写法

// 报错
let {foo: {bar}} = {baz: 'baz'};


(1)如果要将一个已经声明的变量用于解构赋值,必须非常小心。

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error

上面代码的写法会报错,因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

// 正确的写法
let x;
({x} = {x: 1});

3.默认值

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"

4.字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';
len // 5

5.函数参数的解构赋值

函数的参数也可以使用解构赋值。
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3


[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

3.字符串扩展方法

1.字符的Unincode 表示法

ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。

"\u0061"
// "a"

但是,这种表示法只限于码点在\u0000~\uFFFF之间的字符。超出这个范围的字符,必须用两个双字节的形式表示。


"\uD842\uDFB7"
// "?"

"\u20BB7"
// " 7"

上面代码表示,如果直接在\u后面跟上超过0xFFFF的数值(比如\u20BB7),JavaScript 会理解成\u20BB+7。由于\u20BB是一个不可打印字符,所以只会显示一个空格,后面跟着一个7。

ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符

"\u{20BB7}"
// "?"

"\u{41}\u{42}\u{43}"
// "ABC"

let hello = 123;
hell\u{6F} // 123

'\u{1F680}' === '\uD83D\uDE80'
// true



上面代码中,最后一个例子表明,大括号表示法与四字节的 UTF-16 编码是等价的。

有了这种表示法之后,JavaScript 共有 6 种方法可以表示一个字符。

'\z' === 'z'  // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true

2.字符串的遍历器接口

for of

字符串的遍历器接口

ES6 为字符串添加了遍历器接口(详见《Iterator》一章),使得字符串可以被for...of循环遍历。

for (let codePoint of 'foo') {
  console.log(codePoint)
}
// "f"
// "o"
// "o"
除了遍历字符串,这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点。

let text = String.fromCodePoint(0x20BB7);

for (let i = 0; i < text.length; i++) {
  console.log(text[i]);
}
// " "
// " "

for (let i of text) {
  console.log(i);
}
// "?"
上面代码中,字符串text只有一个字符,但是for循环会认为它包含两个字符(都不可打印),而for...of循环会正确识别出这一个字符。

直接输入 U+2028 和 U+2029
JavaScript 字符串允许直接输入字符,以及输入字符的转义形式。举例来说,“中”的 Unicode 码点是 U+4e2d,你可以直接在字符串里面输入这个汉字,也可以输入它的转义形式\u4e2d,两者是等价的。

'中' === '\u4e2d' // true

4.最重要的一点 字符串模板

传统
$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

ES6模板

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

${basket.count} // 动态数据 可以放入任何数据

1.模板编译

let template = `
<ul>
  <% for(let i=0; i < data.supplies.length; i++) { %>
    <li><%= data.supplies[i] %></li>
  <% } %>
</ul>
`;


上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置 JavaScript 代码,使用<%= ... %>输出 JavaScript 表达式。

2.标签模板

模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。

alert`123`
// 等同于
alert(123)


但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。

let a = 5;
let b = 10;

tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);



function tag(stringArr, value1, value2){
  // ...
}

// 等同于

function tag(stringArr, ...values){
  // ...
}

详解见:http://es6.ruanyifeng.com/#docs/string#%E5%AD%97%E7%AC%A6%E7%9A%84-Unicode-%E8%A1%A8%E7%A4%BA%E6%B3%95

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ES6是ECMAScript 2015的简称,是JavaScript的一个重要的更新版本。深入理解ES6 PDF是一本通过深入研究ES6标准来理解其中各种语法和特性的书籍。 这本书分为十八章,从ES6的基础语法和新特性入手,详细讲解了ES6的语法、语义和使用方法。其中包括了箭头函数、简化的对象字面量、模板字面量、解析器、新的控制结构、类和继承、生成器和迭代器、异步操作、Symbol和迭代器、集合和迭代器、Map和Set、新的数组方法、Promise和异步操作、代理和反射、模块化和导入机制,每一章都是围绕特定的内容展开细致的解读。 对于学习ES6的开发者来说,这本书是一份非常有价值的资料。读者可以从中深入了解ES6的语言架构和语法规范,更加深入地理解JavaScript的基础和高级语言特性。对于从ES5升级到ES6的开发者来说,该书是学习ES6语言的最佳手册,还可以通过实例代码快速掌握ES6的语言特性。 总之,深入理解ES6 PDF是一本非常专业且详细的技术书籍,可以帮助读者深入了解ES6语言特性,并掌握新的编程技巧。 ### 回答2: ES6是Javascript的下一代语言标准,它引入了许多新的语法、特性和API,使得编程变得更加简单、高效、灵活和快捷。深入理解ES6 PDF是一本ES6入门指南,它帮助读者系统地学习ES6的核心知识和技能,了解ES6的语法、模块、类、迭代器、生成器、Promise等核心概念及其实践应用。 阅读深入理解ES6 PDF,首先需要了解ES6的基本语法和新特性,包括箭头函数、模板字符串、解构赋值、默认参数、rest参数等。其次,需要学习ES6的模块化设计,了解如何实现模块导出、导入、依赖管理等功能,以便更好地组织代码和提高代码的复用性。另外,深入理解ES6 PDF也介绍了ES6的面向对象编程特性,包括类的声明、方法的定义、继承、多态等,以及ES6的迭代器、生成器、Promise等核心概念及其实践应用,使得读者可以更加深入地掌握ES6的精髓和应用。 综上所述,深入理解ES6 PDF是一本非常好的ES6入门指南,它帮助读者了解ES6的核心知识和技能,带领读者建立ES6的编程思想和风格,以便更好地应对现代Web应用开发的挑战,同时也是学习ES6语言的必备指南。 ### 回答3: 《深入理解ES6》是一本详细介绍ES6新特性的书籍。它主要介绍了模板字符串、解构赋值、箭头函数、类、模块化开发等ES6的新语法。通过深入阅读这本书,能够更好地理解和运用ES6的新特性。 其中,模板字符串是ES6引入的一个非常重要的新特性,它可以让我们更方便地处理字符串拼接和换行,同时还支持常用的字符串操作方法。 解构赋值则是ES6中的另一个重要特性,它可以让我们更快捷地从一个对象或数组中提取出需要的值,这对于提高代码的可读性和复用性都非常有帮助。 箭头函数是ES6中的又一个新特性,它可以让我们更愉悦地编写函数,并且它的this指向也更加方便和易懂。同时也是优化了ES5语言中函数语法臃肿和拖沓的问题。 类是ES6中一个重要的新特性,它可以让我们更加方便地实现面向对象编程,这是在ES5中较为繁琐的过程,同时也减少了ES5类的一些使用致命局限。 最后,模块化开发也是ES6中的一个重要特性,它可以让我们更加方便地组织和管理代码,同时也减少了代码间的相互污染,使得代码更加易于维护和扩展。 总之,《深入理解ES6》这本书为我们深入了解ES6的新特性提供了很好的指导和方向,并且还有配套的演示代码,非常值得一读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值