evantianx / Bloooooooog

Place to record what I thought and learned
0 stars 0 forks source link

Understanding ECMAScript 6 要点小结 #21

Open evantianx opened 7 years ago

evantianx commented 7 years ago

块级绑定

const和let的异同

同:

异:

全局块级绑定

在全局下,用const或let声明不会为window添加属性。

最佳实践

默认情况下使用const,只有明确知道变量值需要修改的情况下使用let。

evantianx commented 7 years ago

函数

函数默认值

若某个参数有默认值,则在相应位置传入undefined或不传值时会调用默认值,而传入null则会使用null。

//ES5严格模式下
function mixArgs(first, second) {
    "use strict";

    console.log(first === arguments[0]);
    console.log(second === arguments[1]);
    first = "c";
    second = "d"
    console.log(first === arguments[0]);
    console.log(second === arguments[1]);
}

mixArgs("a", "b");
/*
* true
* true
* false
* false
*/
// 非严格模式
function mixArgs(first, second = "b") {
    console.log(arguments.length);
    console.log(first === arguments[0]);
    console.log(second === arguments[1]);
    first = "c";
    second = "d"
    console.log(first === arguments[0]);
    console.log(second === arguments[1]);
}

mixArgs("a");  
/*
* 1
* true
* false
* false
* false
*/

意味着无论是否在严格模式下,始终可以依据arguements对象来反映初始调用状态。

函数构造器的加强

使用new Function动态创建函数时,参数可以使用默认参数和剩余参数

var pickFirst = new Function("...args", "return args[0]");

console.log(pickFirst(1, 2)); // 1
var add = new Function("first", "second = first", "return first + second");

console.log(add(2,2));  // 4
console.log(add(2));    // 4

扩展运算符

使用扩展运算符传递参数,使得将数组作为函数参数使用更为容易。

let values = [2, 3, 6, 1];

console.log(Math.max(...values, 0));

函数name属性

在ES6中所有函数均有name属性值。

function doSomething() {
    //...
}

var doSomethingElse = function doAnythingElse() {
    // ...
};

console.log(doSomething.name); // "doSomething"
console.log(doSomethingElse.name); //"doAnythingElse"

块级函数

在ES5严格模式下不允许在代码块内部声明函数:

"use strict"

if(true) {
   //在ES5会抛出错误,而ES6不会
   function doSomething() {
     //...
   }
}

ES6会将该函数视为块级函数,同时会被提升到定义所在代码块的顶部(严格模式下如此,在非严格模式下则会提升至全局),代码块执行完毕则销毁该函数。

使用let函数表达式同样可以形成块级函数,区别在于let函数表达式不会提升

箭头函数

特征:

语法:

// 无参数
var getName = () => "Nicholas";
// 一个参数
var reflect = value => value;
// 多参数
var sum = (a, b) => a+b;
// 空函数
var empty = () => {};
// 返回值为一个对象(对象字面量必须用圆括号包裹)
var getItem = id => ({ id: id, name: "item" })'

如何利用箭头函数创建IIFE?

//以前的写法:
(function() { /*函数体*/ })();
(function() {/*函数体*/}())

//箭头函数写法
//只能这样写!
(() => {/*函数体*/})()

关于箭头函数的this: 箭头函数没有this绑定,所以箭头函数内部的this值只能通过查找作用域链来确定。若箭头函数被包含于一个非箭头函数内,那么this值就会与该函数的相等。

因此不能用call()apply()bind()方法来改变其this值。

没有arguments绑定: 不能访问自身的参数对象,但是可以访问包含它的函数的arguments对象。

evantianx commented 7 years ago

扩展的对象功能

对象字面量语法的扩展

属性初始化器的速记法

//之前属性值初始化写法
function createPerson(name, age) {
  return {
    name: name,
    age: age
  }
}

//ES6中写法
function createRobot(name, age) {
  return {
    name,
    age
  }
}

方法简写

//之前方法写法:
var person = {
  name: "Nicholas",
  sayName: function() {
    console.log(this.name);
  }
}

//ES6写法
var robot = {
  name: "Dolores",
  sayName() {
    console.log(this.name);
  }
}

需计算属性名 在ES6中,属性名可以这样写:

var suffix = " name";

var person = {
  ["first" + suffix]: "Nicholas",
  ["last" + suffix]: "Zakas"
}

console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); //"Zakas"

新增方法

Object.is() 用来比较。接受两个参数,两者类型和值都相等时返回true(NaN 等于 NaN,+0不等于-0)

Object.assign() 合并对象,接受一个接受者,多个供应者,而第二个供应者的属性可能会覆盖第一个供应者的属性

重复的对象字面量属性

在ES5中,对象的属性名若出现重复则会报错;在ES6中不会报错,且属性值采用后面的属性值。