[譯]ES6簡明參考手冊

本文翻譯自github上的一篇文章
原文地址:https://github.com/DrkSephy/es6-cheatsheet

es6-參考手冊

該手冊包括ES2015[ES6]的知識點、技巧、建議和每天工作用的代碼段例子蠕趁。歡迎補充和建議锣光。

var 和 let / const

除了var,我們現(xiàn)在有了兩種新的標示符用來存儲值——letconst。與var不同的是,letconst 聲明不會提前到作用域的開頭。(譯注:即不發(fā)生聲明提前)

一個使用var的例子:

var snack = 'Meow Mix';

function getFood(food) {
    if (food) {
        var snack = 'Friskies';
        return snack;
    }
    return snack;
}

getFood(false); // undefined

然而, 我們把var替換成let,觀察會發(fā)生什么:

let snack = 'Meow Mix';

function getFood(food) {
    if (food) {
        let snack = 'Friskies';
        return snack;
    }
    return snack;
}

getFood(false); // 'Meow Mix'

這種行為變化提示我們埠况,在使用var重構遺留代碼的時候需要小心,盲目的把let替換成var會導致以外的行為

注意: letconst具有塊作用域棵癣。因此在它們定義前調用會引發(fā)ReferenceError

console.log(x); // ReferenceError: x is not defined

let x = 'hi';

建議:在遺留代碼中的保留var聲明表示需要小心的重構辕翰。在新建代碼庫時,使用let聲明以后會只會發(fā)生改變的變量狈谊,用const聲明那些以后不會被改變的變量喜命。

譯注:const修飾的基本類型不能改變沟沙,而其修飾的對象、函數(shù)壁榕、數(shù)組等引用類型矛紫,可以改變內部的值,但不能改變其引用牌里。

用塊(Blocks)替換立即執(zhí)行函數(shù)(IIFEs)

立即執(zhí)行函數(shù)常被用作閉包颊咬,把變量控制在作用域內。在ES6中牡辽,我們可以創(chuàng)建一個塊作用域而且不僅僅是基于函數(shù)的作用域贪染。

(function () {
    var food = 'Meow Mix';
}());

console.log(food); // Reference Error
Using ES6 Blocks:

{
    let food = 'Meow Mix';
};

console.log(food); // Reference Error

箭頭函數(shù)(Arrow Functions)

通常我們會建立嵌套函數(shù),當我們想保留this上下文作用域的時候(該怎么辦?)催享。如下就是一個例子:

function Person(name) {
    this.name = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map(function (character) {
        return this.name + character; // Cannot read property 'name' of undefined
    });
};

一個常見的解決方法是利用一個變量存儲這個this的上下文。

function Person(name) {
    this.name = name;
}

Person.prototype.prefixName = function (arr) {
    var that = this; // Store the context of this
    return arr.map(function (character) {
        return that.name + character;
    });
};

我們也可以傳入這個this的上下文:

function Person(name) {
    this.name = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map(function (character) {
        return this.name + character;
    }, this);
};

還可以用bind綁定這個上下文:

function Person(name) {
    this.name = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map(function (character) {
        return this.name + character;
    }.bind(this));
};

使用箭頭函數(shù)哟绊,this的詞法作用域不會被影響因妙,我們可以像以下這樣重寫之前的代碼

function Person(name) {
    this.name = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map(character => this.name + character);
};

建議: 只要當你想保留this的詞法作用域時,就使用箭頭函數(shù)

對于一個簡單返回一個值的函數(shù)來說票髓,箭頭函數(shù)顯得更加簡潔

var squares = arr.map(function (x) { return x * x }); // Function Expression
const arr = [1, 2, 3, 4, 5];
const squares = arr.map(x => x * x); // Arrow Function for terser implementation

建議: 盡可能用箭頭函數(shù)替換你的函數(shù)定義

字符串(Strings)

在ES6中, 標準庫也在不斷的擴充攀涵。在這些變化中就有很多方法可以用于字符串,比如.includes().repeat()

.includes()

var string = 'food';
var substring = 'foo';

console.log(string.indexOf(substring) > -1);

檢測返回值是否大于-1表示字符串是否存在洽沟,我們可以用.includes()替換以故,它返回一個boolean值。

const string = 'food';
const substring = 'foo';

console.log(string.includes(substring)); // true

.repeat()

function repeat(string, count) {
    var strings = [];
    while(strings.length < count) {
        strings.push(string);
    }
    return strings.join('');
}

在ES6中裆操,我們一種更簡潔的實現(xiàn)方法:

// String.repeat(numberOfRepetitions)
'meow'.repeat(3); // 'meowmeowmeow'

模板字面量(Template Literals)

(譯注:原文是Template Literals怒详,而非Template Strings)

利用模板字面量,我們可以直接在字符串使用特殊字符而不用轉義它們踪区。

var text = "This string contains \"double quotes\" which are escaped.";
let text = `This string contains "double quotes" which don't need to be escaped anymore.`;

模板字面量還支持插值昆烁,可以輕松完成連接字符串和值的任務:

var name = 'Tiger';
var age = 13;

console.log('My cat is named ' + name + ' and is ' + age + ' years old.');
const name = 'Tiger';
const age = 13;

console.log(`My cat is named ${name} and is ${age} years old.`);

在ES5中,我們這樣操作多行字符串:

var text = (
    'cat\n' +
    'dog\n' +
    'nickelodeon'
);

或者

var text = [
    'cat',
    'dog',
    'nickelodeon'
].join('\n');

模板字面量可以保留多行字符串缎岗,我們無需顯式的放置它們:

let text = ( `cat
dog
nickelodeon`
);

模板字面量可以接受表達式, 比如:

let today = new Date();
let text = `The time and date is ${today.toLocaleString()}`;

解構賦值(Destructuring)

解構賦值允許我們從數(shù)組或對象中提取出值(甚至深度嵌套的值)静尼,并把他們存入變量的簡單語法

解構數(shù)組(Destructuring Arrays)

var arr = [1, 2, 3, 4];
var a = arr[0];
var b = arr[1];
var c = arr[2];
var d = arr[3];
let [a, b, c, d] = [1, 2, 3, 4];

console.log(a); // 1
console.log(b); // 2

解構對象(Destructuring Objects)

var luke = { occupation: 'jedi', father: 'anakin' };
var occupation = luke.occupation; // 'jedi'
var father = luke.father; // 'anakin'
let luke = { occupation: 'jedi', father: 'anakin' };
let {occupation, father} = luke;

console.log(occupation); // 'jedi'
console.log(father); // 'anakin'

模塊(Modules)

ES6之前,我們只用如Browserify的庫在客戶端創(chuàng)建模塊传泊,并且需要用到Node.js鼠渺。利用ES6,我們現(xiàn)在可以直接使用任何類型的模塊(AMD和CommonJS)

CommonJS中的exports

module.exports = 1;
module.exports = { foo: 'bar' };
module.exports = ['foo', 'bar'];
module.exports = function bar () {};

ES6中的export

在ES6中眷细,提供各種不同類型的exports拦盹,我們可以運行如下:

export let name = 'David';
export let age  = 25;??

輸出對象列表:

function sumTwo(a, b) {
    return a + b;
}

function sumThree(a, b, c) {
    return a + b + c;
}

export { sumTwo, sumThree };

我們也可以簡單地通過export關鍵字輸出函數(shù)、對象和值(等等):

export function sumTwo(a, b) {
    return a + b;
}

export function sumThree(a, b, c) {
    return a + b + c;
}
And lastly, we can export default bindings:

function sumTwo(a, b) {
    return a + b;
}

function sumThree(a, b, c) {
    return a + b + c;
}

let api = {
    sumTwo,
    sumThree
};

輸出默認api:

/* Which is the same as
 * export { api as default };
 */

建議:在模塊結束的地方薪鹦,始終輸出默認的方法掌敬。這樣可以清晰地看到接口惯豆,并且通過弄清楚輸出值的名稱節(jié)省時間。所以在CommonJS模塊中通常輸出一個對象或值奔害。堅持使用這種模式楷兽,會使我們的代碼易讀,并且可以輕松的在ES6和CommonJS中進行插補华临。

ES6

ES6 提供提供各種不同的imports,我們輸入一整個文件:

import 'underscore';

這里值得注意的是芯杀,簡單的輸入一文件會在文件的最頂層執(zhí)行代碼。和Python類似雅潭,我們已經命名了imports:

import { sumTwo, sumThree } from 'math/addition';

我們還可以重命名這些已經有名的imports:

import {
    sumTwo as addTwoNumbers,
    sumThree as sumThreeNumbers
} from 'math/addition';

此外揭厚,我們可以輸入各種東西(也叫做 namespace import)

import * as util from 'math/addition';

最后,我們可以從模塊輸入一列值:

import * as additionUtil from 'math/addition';
const { sumTwo, sumThree } = additionUtil;

如下這樣從默認綁定進行輸入

import api from 'math/addition';
// 例如: import { default as api } from 'math/addition';

雖然最好要保持輸出簡單扶供,但是如果我們需要筛圆,我們有時可以混用默認輸入,當我們想如下輸出的時候:

// foos.js
export { foo as default, foo1, foo2 };

我們可以如下輸入它們:

import foo, { foo1, foo2 } from 'foos';

當使用commonj語法(如React)輸入一個模型的輸出時椿浓,我們可以這樣做:

import React from 'react';
const { Component, PropTypes } = React;

這個也可以進一步簡化太援,使用:

import React, { Component, PropTypes } from 'react';

注意:輸出的值是綁定,不是引用扳碍。因此提岔,綁定的值發(fā)生變化會影響輸出的模型中的值。避免修改這些輸出值的公共接口笋敞。

參數(shù)(Parameters)

在ES5中碱蒙,我們可以很多方法操作函數(shù)參數(shù)的默認值、未定義的參數(shù)和有定義的參數(shù)夯巷。在ES6中赛惩,我們可以用更簡單的語法實現(xiàn)這一切。

默認參數(shù)(Default Parameters)

function addTwoNumbers(x, y) {
    x = x || 0;
    y = y || 0;
    return x + y;
}

在ES6中趁餐,我們可以簡單的把默認值賦給參數(shù):

function addTwoNumbers(x=0, y=0) {
    return x + y;
}
addTwoNumbers(2, 4); // 6
addTwoNumbers(2); // 2
addTwoNumbers(); // 0

剩余參數(shù)(Rest Parameters)

在ES5中坊秸,我們這樣操作一個未定義的參數(shù):

function logArguments() {
    for (var i=0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}

使用休止符(...)我們可以傳入大量未定義的參數(shù):

function logArguments(...args) {
    for (let arg of args) {
        console.log(arg);
    }
}

已命名的參數(shù)(Named Parameters)

ES5中,一種處理已命名參數(shù)的方式是使用選項方式澎怒,這種方法來自jQuery褒搔。

function initializeCanvas(options) {
    var height = options.height || 600;
    var width  = options.width  || 400;
    var lineStroke = options.lineStroke || 'black';
}

通過解構成正式參數(shù)的方式,我們可以實現(xiàn)同樣的功能:

function initializeCanvas(
{ height=600, width=400, lineStroke='black'}) {
    // Use variables height, width, lineStroke here
}

如果我們想使全部參數(shù)值可選喷面,我們可以用一個空對象這樣結構:

function initializeCanvas(
    { height=600, width=400, lineStroke='black'} = {}) {
        // ...
    }

展開運算符(Spread Operator)

在ES5中星瘾,查找一個array中的最大值需要使用Math.max的apply方法:

Math.max.apply(null, [-1, 100, 9001, -32]); // 9001

在es6中,我們使用展開運算符將array傳遞給函數(shù)作為參數(shù):

Math.max(...[-1, 100, 9001, -32]); // 9001

我們可以用這樣簡潔的語法鏈接數(shù)組字面量:

let cities = ['San Francisco', 'Los Angeles'];
let places = ['Miami', ...cities, 'Chicago']; // ['Miami', 'San Francisco', 'Los Angeles', 'Chicago']

類(classes)

在ES6之前惧辈,我們通過創(chuàng)建構造器函數(shù)琳状,并且在其prototype上添加屬性的方法創(chuàng)建一個類:

function Person(name, age, gender) {
    this.name   = name;
    this.age    = age;
    this.gender = gender;
}

Person.prototype.incrementAge = function () {
    return this.age += 1;
};

并且用一下方法創(chuàng)建繼承類:

function Personal(name, age, gender, occupation, hobby) {
    Person.call(this, name, age, gender);
    this.occupation = occupation;
    this.hobby = hobby;
}

Personal.prototype = Object.create(Person.prototype);
Personal.prototype.constructor = Personal;
Personal.prototype.incrementAge = function () {
    Person.prototype.incrementAge.call(this);
    this.age += 20;
    console.log(this.age);
};

ES6 提供了十分有用的句法在后臺實現(xiàn)這一切,我們可以這樣直接創(chuàng)建一個類:

class Person {
    constructor(name, age, gender) {
        this.name   = name;
        this.age    = age;
        this.gender = gender;
    }

    incrementAge() {
      this.age += 1;
    }
}

并且用關鍵字extends實現(xiàn)繼承:

class Personal extends Person {
    constructor(name, age, gender, occupation, hobby) {
        super(name, age, gender);
        this.occupation = occupation;
        this.hobby = hobby;
    }

    incrementAge() {
        super.incrementAge();
        this.age += 20;
        console.log(this.age);
    }
}

建議:使用ES6的語法創(chuàng)建類模糊了后臺的實現(xiàn)和原型如何工作盒齿,這個好特性可以使我們的代碼更整潔念逞。

Symbols

Symbol在ES6之前就已經出現(xiàn)了, 但是現(xiàn)在我們有了一個公共的接口可以直接使用困食。Symbol是唯一且不可改變的值,被用作哈希中的鍵翎承。

Symbol()

調用Symbol()或者Symbol(description)會創(chuàng)建一個不能在全局查找的獨一無二的符號硕盹。一種使用symbol()的情況是,利用自己的邏輯修補第三方的對象或命名空間叨咖,但不確定會不會在庫更新時產生沖突瘩例。例如,如果你想添加一個方法refreshCompontentReact.Component甸各,并且確信這個方法他們不會在以后的更新中添加垛贤。

const refreshComponent = Symbol();

React.Component.prototype[refreshComponent] = () => {
    // do something
}

###Symbol.for(key)

Symbol.for(key) 依然會創(chuàng)建一個唯一且不能修改的Symbol,但是它可以在全局被查找趣倾。兩次調用相同的Symbol.for(key) 會創(chuàng)建一樣的Symbol實例聘惦。注意,他和Symbol(description)不是相同的:

Symbol('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol.for('foo') // true

一個常見的symbol方法Symbol.for(key)是可互操作的儒恋。(使用這個方法)這個可以通過使用自己的代碼在包括已知接口的第三方的對象參數(shù)中查找symbol成員實現(xiàn)部凑,例如:

function reader(obj) {
    const specialRead = Symbol.for('specialRead');
    if (obj[specialRead]) {
        const reader = obj[specialRead]();
        // do something with reader
    } else {
        throw new TypeError('object cannot be read');
    }
}

在另一個庫中:

const specialRead = Symbol.for('specialRead');

class SomeReadableType {
    [specialRead]() {
        const reader = createSomeReaderFrom(this);
        return reader;
    }
}

ES6中,一個值得注意的是關于Symbol的互操作性的例子是Symbol.iterator碧浊,它存在于Arrays、Strings瘟仿、Generators等等的所有可迭代類型中箱锐。當作為一個方法調用的時候,它會返回一個具有迭代器接口的對象劳较。

Maps

Maps是JavaScript中十分有用的結構驹止。在ES6之前, 我們通過對象創(chuàng)建哈希maps:

var map = new Object();
map[key1] = 'value1';
map[key2] = 'value2';

但是,這樣不能保護我們對已有屬性以外的重寫:

> getOwnProperty({ hasOwnProperty: 'Hah, overwritten'}, 'Pwned');
> TypeError: Property 'hasOwnProperty' is not a function

Map允許我們使用set观蜗、get和search(等等)訪問屬性值臊恋。

let map = new Map();
> map.set('name', 'david');
> map.get('name'); // david
> map.has('name'); // true

最意想不到的是Map不再限制我們只使用字符串作為鍵,我們現(xiàn)在可以使用任何類型作為鍵而不會發(fā)生類型轉換墓捻。

let map = new Map([
    ['name', 'david'],
    [true, 'false'],
    [1, 'one'],
    [{}, 'object'],
    [function () {}, 'function']
]);

for (let key of map.keys()) {
    console.log(typeof key);
    // > string, boolean, number, object, function
}

注意:當使用如map.get()等方法測試相等的時候抖仅,諸如function和object這樣的非原始值不能正常工作。因此砖第,依然應該使用原始值(作為鍵)撤卢,比如String、Boolean和Number梧兼。
我們也可以使用.entries()方法作為迭代器遍歷Map

for (let [key, value] of map.entries()) {
    console.log(key, value);
}

WeakMaps

ES6之前放吩,為了保存私有數(shù)據,我們采取了很多方式羽杰。其中一個方法就是命名轉換:

class Person {
    constructor(age) {
        this._age = age;
    }

    _incrementAge() {
        this._age += 1;
    }
}

但是命名轉換會引起代碼庫混亂渡紫,并且不能保證總是被支持到推。為此,我們使用WeakMaps存儲數(shù)據:

let _age = new WeakMap();
class Person {
    constructor(age) {
        _age.set(this, age);
    }

    incrementAge() {
        let age = _age.get(this) + 1;
        _age.set(this, age);
        if (age > 50) {
            console.log('Midlife crisis');
        }
    }
}

使用WeakMap存儲數(shù)據時的一個很有趣的事情是惕澎,這個key不會暴露出屬性名莉测,需要使用Reflect.ownKeys()實現(xiàn):

> const person = new Person(50);
> person.incrementAge(); // 'Midlife crisis'
> Reflect.ownKeys(person); // []

使用WeakMap更實際的例子是在不污染DOM自身的情況下存儲與DOM元素相關的數(shù)據:

let map = new WeakMap();
let el  = document.getElementById('someElement');

// 給元素存一個弱引用
map.set(el, 'reference');

// 獲得元素的值
let value = map.get(el); // 'reference'

// 移除引用
el.parentNode.removeChild(el);
el = null;

// 元素被回收后,map是空的

如上所示集灌,當一個對象被GC回收后悔雹,WeakMap會自動移除以其為標識符的鍵值對。

注意:為了進一步說明這個例子的實用性欣喧。當一個與DOM對應的對象的具有引用時腌零,考慮jQuery如何存儲它。使用WeakMaps唆阿,jQuery可以在DOM元素被刪除時自動釋放與之關聯(lián)的內存益涧。總而言之驯鳖,對任何庫而言闲询,WeakMaps對操作DOM元素是非常實用的。

Promises

Promise允許我們把水平的代碼(回調函數(shù)的地獄):

func1(function (value1) {
    func2(value1, function (value2) {
        func3(value2, function (value3) {
            func4(value3, function (value4) {
                func5(value4, function (value5) {
                    // Do something with value 5
                });
            });
        });
    });
});

轉換為豎直的代碼:

func1(value1)
    .then(func2)
    .then(func3)
    .then(func4)
    .then(func5, value5 => {
        // Do something with value 5
    });

在ES6之前浅辙,我們使用bluebird或是Q扭弧,現(xiàn)在我們有了Promises:

new Promise((resolve, reject) =>
    reject(new Error('Failed to fulfill Promise')))
        .catch(reason => console.log(reason));

這里我們有2個handlers,resolve(Promise執(zhí)行成功時調用的函數(shù))和reject(Promise失敗時調用的函數(shù))记舆。

使用Promise的好處:使用嵌套的回調函數(shù)處理錯誤會很混亂鸽捻。使用Promise,我們可以很清晰的使錯誤冒泡泽腮,并且就近處理它們御蒲。更好的是,在它處理成功(或失斦锷蕖)之后Promise的值是不可修改的厚满。

以下是個使用Promise的實例:

var request = require('request');

return new Promise((resolve, reject) => {
  request.get(url, (error, response, body) => {
    if (body) {
        resolve(JSON.parse(body));
      } else {
        resolve({});
      }
  });
});

我們可以使用Promise.all()并行的處理一個異步操作數(shù)組:

let urls = [
  '/api/commits',
  '/api/issues/opened',
  '/api/issues/assigned',
  '/api/issues/completed',
  '/api/issues/comments',
  '/api/pullrequests'
];

let promises = urls.map((url) => {
  return new Promise((resolve, reject) => {
    $.ajax({ url: url })
      .done((data) => {
        resolve(data);
      });
  });
});

Promise.all(promises)
  .then((results) => {
    // Do something with results of all our promises
 });

Generators

和Promise使我們避免回調函數(shù)的地獄相似,Generators可以扁平化我們的代碼——給我們一種同步執(zhí)行異步代碼的感覺碧磅,Generators是個很重要的函數(shù)碘箍,它使我們可以暫停操作的執(zhí)行,隨后返回表達式的值鲸郊。

下面是使用Generator的一個簡單例子:

function* sillyGenerator() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
}

var generator = sillyGenerator();
> console.log(generator.next()); // { value: 1, done: false }
> console.log(generator.next()); // { value: 2, done: false }
> console.log(generator.next()); // { value: 3, done: false }
> console.log(generator.next()); // { value: 4, done: false }

這里敲街,next()使我們generator繼續(xù)推進,并且得到新的表達式的值(譯注:每次推進到下一個yield值)严望。當然多艇,上面的例子很牽強,我們可以利用Generator以同步的方式寫異步代碼:

// 利用Generator屏蔽異步過程

function request(url) {
    getJSON(url, function(response) {
        generator.next(response);
    });
}

下面我們寫一個generator函數(shù)用來返回我們自己的數(shù)據:

function* getData() {
    var entry1 = yield request('http://some_api/item1');
    var data1  = JSON.parse(entry1);
    var entry2 = yield request('http://some_api/item2');
    var data2  = JSON.parse(entry2);
}

利用yield的功能像吻,我們確保entry1可以獲得返回的數(shù)據峻黍,用于解析并存儲到data1中复隆。
當我們利用generator以同步的方式寫異步的代碼時,其中的錯誤不會簡單清晰的傳遞姆涩。因此挽拂,我們利用Promise加強generator:

function request(url) {
    return new Promise((resolve, reject) => {
        getJSON(url, resolve);
    });
}

我們寫了一個函數(shù),利用next用來按序地一步步遍歷generator骨饿。該函數(shù)利用上述的請求方式并yeild一個Promise(對象)亏栈。

function iterateGenerator(gen) {
    var generator = gen();
    (function iterate(val) {
        var ret = generator.next();
        if(!ret.done) {
            ret.value.then(iterate);
        }
    })();
}

通過Promise加強generator后,我們可以利用Promise.catch和Promise.reject這樣清晰的方式傳播錯誤宏赘。只用這個加強版的Generator和以前一樣簡單:

iterateGenerator(function* getData() {
    var entry1 = yield request('http://some_api/item1');
    var data1  = JSON.parse(entry1);
    var entry2 = yield request('http://some_api/item2');
    var data2  = JSON.parse(entry2);
});

我們可以重用寫好的代碼绒北,像過去使用Generator一樣,這一點很強大察署。當我們利用generator以同步的方式寫異步的代碼的同時闷游,利用一個不錯的方式保留了錯誤傳播的能力,我們實際上可以利用一個更為簡單的方式達到同樣的效果:異步等待(Async-Await)贴汪。

Async Await

這是一個在ES2016(ES7)中即將有的特性脐往,async await允許我們更簡單地使用Generator和Promise執(zhí)行和已完成工作相同的任務:

var request = require('request');

function getJSON(url) {
  return new Promise(function(resolve, reject) {
    request(url, function(error, response, body) {
      resolve(body);
    });
  });
}

async function main() {
  var data = await getJSON();
  console.log(data); // NOT undefined!
}

main();

在后臺,它的實現(xiàn)類似Generators扳埂。我(作者)強烈建議使用這個替代Generators + Promises业簿。還會有很多的資源出現(xiàn)并使用ES7,同時阳懂,Babel也會用在這里梅尤。

Getter 和 Setter 函數(shù)

ES6 已經支持了GetterSetter函數(shù),例如:

class Employee {

    constructor(name) {
        this._name = name;
    }

    get name() {
      if(this._name) {
        return 'Mr. ' + this._name.toUpperCase();  
      } else {
        return undefined;
      }  
    }

    set name(newName) {
      if (newName == this._name) {
        console.log('I already have this name.');
      } else if (newName) {
        this._name = newName;
      } else {
        return false;
      }
    }
}

var emp = new Employee("James Bond");

// 內部使用了get方法
if (emp.name) {
  console.log(emp.name);  // Mr. JAMES BOND
}

// 內部使用了setter(譯注:原文中這一句和上一句注釋的表述就這么不一樣)
emp.name = "Bond 007";
console.log(emp.name);  // Mr. BOND 007  

最新的瀏覽器都支持對象中的getter/setter函數(shù)希太,我們可以使用他們計算屬性、添加事件以及在setting和getting前的預處理

var person = {
  firstName: 'James',
  lastName: 'Bond',
  get fullName() {
      console.log('Getting FullName');
      return this.firstName + ' ' + this.lastName;
  },
  set fullName (name) {
      console.log('Setting FullName');
      var words = name.toString().split(' ');
      this.firstName = words[0] || '';
      this.lastName = words[1] || '';
  }
}

person.fullName; // James Bond
person.fullName = 'Bond 007';
person.fullName; // Bond 007
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末酝蜒,一起剝皮案震驚了整個濱河市誊辉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亡脑,老刑警劉巖堕澄,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異霉咨,居然都是意外死亡蛙紫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門途戒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坑傅,“玉大人,你說我怎么就攤上這事喷斋⊙涠荆” “怎么了蒜茴?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浆西。 經常有香客問我粉私,道長,這世上最難降的妖魔是什么近零? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任诺核,我火速辦了婚禮,結果婚禮上久信,老公的妹妹穿的比我還像新娘窖杀。我一直安慰自己,他們只是感情好入篮,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布陈瘦。 她就那樣靜靜地躺著,像睡著了一般潮售。 火紅的嫁衣襯著肌膚如雪痊项。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天酥诽,我揣著相機與錄音鞍泉,去河邊找鬼。 笑死肮帐,一個胖子當著我的面吹牛咖驮,可吹牛的內容都是我干的。 我是一名探鬼主播训枢,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼托修,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恒界?” 一聲冷哼從身側響起睦刃,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎十酣,沒想到半個月后涩拙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡耸采,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年兴泥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虾宇。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡搓彻,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情好唯,我是刑警寧澤竭沫,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站骑篙,受9級特大地震影響蜕提,放射性物質發(fā)生泄漏。R本人自食惡果不足惜靶端,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一谎势、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杨名,春花似錦脏榆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趁蕊,卻和暖如春坞生,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掷伙。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工是己, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人任柜。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓卒废,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宙地。 傳聞我的和親對象是個殘疾皇子摔认,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容

  • 異步編程對JavaScript語言太重要。Javascript語言的執(zhí)行環(huán)境是“單線程”的宅粥,如果沒有異步編程参袱,根本...
    呼呼哥閱讀 7,311評論 5 22
  • 本文為阮一峰大神的《ECMAScript 6 入門》的個人版提純! babel babel負責將JS高級語法轉義粹胯,...
    Devildi已被占用閱讀 1,983評論 0 4
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評論 0 1
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持蓖柔,譯者再次奉上一點點福利:阿里云產品券辰企,享受所有官網優(yōu)惠风纠,并抽取幸運大...
    HetfieldJoe閱讀 6,377評論 9 19
  • 端午放假,我自然的選擇了不做早飯牢贸,但天生小氣的我,不舍得花錢,希望身邊的這個男人我老公能做早飯臭增,昨天的粥味道還是很...
    孤詣的花田半畝閱讀 265評論 0 0