es6--看es6入门整理

(一)const和let

1.let

       a.暂时性死区(“暂时性死区”也意味着typeof不再是一个百分之百安全的操作),且let不允许在相同作用域内,重复声明同一个变量

      

 2. const

    a.const声明一个只读的常量。一旦声明,常量的值就不能改变,且const一旦声明变量,就必须立即初始化,不能留到以后赋值。

    b.和let一样存在暂时性死区

关于const和let ES6增加了两种定义变量的方法

(关于简单类型的数据和复合类型的数据指针问题以及延伸的对象深拷贝--补)

(二)解构赋值

1.数组的解构赋值(主要)

2.对象的解构赋值(主要)

3.字符串的解构赋值

4.数值和布尔值的解构赋值

5.数值和布尔值的解构赋值

列举了一些主要常用的地方可以在自己的代码中试验一下

(三)字符串的扩展

1.ES6 为字符串添加了遍历器接口

for (let codePoint of 'foo') {
  console.log(codePoint)
}

2.模板字符串 

a.用反引号(`)标识

b.模板字符串中嵌入变量,需要将变量名写在${}之中

JQ 

$('#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!
`);

 可以把之前jq里的动态添加dom变为字符串模版

(四)函数的扩展

1.ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面

function log(x, y) {
  y = y || 'World';
  console.log(x, y);
}

ES6

function log(x, y = 'World') {
  console.log(x, y);
}

2.ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数 ,rest 参数之后不能再有其他参数(即只能是最后一个参数)要注意的是

函数的length属性,不包括 rest 参数

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

3. 箭头函数(重要)

  a.如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

  b.如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来

  c.如果箭头函数的代码块部分只有一条return语句,return可以省略

  d.上面四点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。箭头函数里面根本没有自己的this,而是引用外层的this

 (五)数组的扩展

1.扩展运算符

a.扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。可以替代函数的 apply 方法

Math.max和push都可以很简单的使用扩展运算符

// ES5 的写法
Math.max.apply(null, [14, 3, 77])

// ES6 的写法
Math.max(...[14, 3, 77])
// ES5的 写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);

// ES6 的写法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);

2.复制数组

下面代码中,a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]

 ES5用了下面的方法来进行,concat()和

const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]

ES6用扩展运算符

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

(浅拷贝和深拷贝还不是很清楚)

3.如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错

4.Array.from可以将一些数据结构转为数组

还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);

5. includes(和indexOf功能相仿

indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。

 (六)对象的扩展

1.  属性的简洁表示法

属性简写:

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.name

函数的name属性,返回函数名。对象方法也是函数,因此也有name属性

3.属性的可枚举性和遍历

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。

对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for...in遍历到。

Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
// false

Object.getOwnPropertyDescriptor([], 'length').enumerable
// false

目前,有四个操作会忽略enumerablefalse的属性。

  • for...in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerablefalse的属性,只拷贝对象自身的可枚举的属性。

4.字符串新增方法

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
  • repeat():repeat方法返回一个新字符串,表示将原字符串重复n
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

adStart()的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串

'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"

另一个用途是提示字符串格式

'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

(七)symbol对象

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突

let s = Symbol();

typeof s
// "symbol"

有时,我们希望重新使用同一个 Symbol 值,Symbol.for方法可以做到这一点

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true

Symbol.for()Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值

(八)Set 和 Map 数据结构

1.Set(它类似于数组,但是成员的值都是唯一的,没有重复的值。)

Set本身是一个构造函数,用来生成 Set 数据结构

const s = new Set();
// 去除数组的重复成员
[...new Set(array)]
//去除字符串里面的重复字符。
[...new Set('ababbc')].join('')
// "abc"

Array.from方法可以将 Set 结构转为数组。(数组去重)

function dedupe(array) {
  return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

2.Map(是一种数据结构并非数组的map方法)

1.各种方法

size()(返回 Map 结构的成员总数)

set()(设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键,set方法返回的是当前的Map对象,因此可以采用链式写法)

get()(get方法读取key对应的键值,如果找不到key,返回undefined)

has()(返回一个布尔值,表示某个键是否在当前 Map 对象之中。)

delete()(delete方法删除某个键,返回true。如果删除失败,返回false。)

clear()(清除所有成员,没有返回值)

 2.Map 结构转为数组结构,比较快速的方法是使用扩展运算符(...

(九)promise对象

(十)Iterator

1.Iterator

Iterator 的遍历过程是这样的。

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};
    }
  };
}

2.原生具备 Iterator 接口的数据结构

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

3.调用 Iterator 接口的场合(有一些场合会默认调用 Iterator 接口(即Symbol.iterator方法))

1)解构赋值

2)扩展运算符

3)yield*

4)其他场合

  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]])
  • Promise.all()
  • Promise.race()

类似数组的对象包括好几类。for...of循环可用于字符串、DOM NodeList 对象、arguments对象。

4.对于普通的对象,for...of结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用。但是,这样情况下,for...in循环依然可以用来遍历键名

let es6 = {
  edition: 6,
  committee: "TC39",
  standard: "ECMA-262"
};

for (let e in es6) {
  console.log(e);
}
// edition
// committee
// standard

for (let e of es6) {
  console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function

for...in循环主要是为遍历对象而设计的,不适用于遍历数组

相对于forEach方法和for循环方法,for..of循环作为数组的遍历有显著的优点

  • 有着同for...in一样的简洁语法,但是没有for...in那些缺点。
  • 不同于forEach方法,它可以与breakcontinuereturn配合使用。
  • 提供了遍历所有数据结构的统一操作接口。
for (var n of fibonacci) {
  if (n > 1000)
    break;
  console.log(n);
}

(十一)Generator 函数

1.yield 表达式

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined

2.

function* f() {
  console.log('执行了!')
}

var generator = f();

setTimeout(function () {
  generator.next()
}, 2000);

上面代码中,函数f如果是普通函数,在为变量generator赋值时就会执行。但是,函数f是一个 Generator 函数,就变成只有调用next方法时,函数f才会执行。f变为了暂缓执行函数

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值