diff --git a/README.md b/README.md index 5ede48ef..705f44d5 100644 --- a/README.md +++ b/README.md @@ -293,6 +293,26 @@ Other Style Guides console.log(has.call(object, key)); ``` + + - [3.10](#objects--rest-spread) Prefer the object spread operator over `Object.assign` to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted. + + ```javascript + // very bad + const original = { a: 1, b: 2 }; + const copy = Object.assign(original, { c: 3 }); // this mutates `original` ಠ_ಠ + delete copy.a; // so does this + + // bad + const original = { a: 1, b: 2 }; + const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 } + + // good + const original = { a: 1, b: 2 }; + const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 } + + const { a, ...noA } = copy; // noA => { b: 2, c: 3 } + ``` + **[⬆ back to top](#table-of-contents)** ## Arrays diff --git a/packages/eslint-config-airbnb-base/.eslintrc b/packages/eslint-config-airbnb-base/.eslintrc index 6c8556be..224149fd 100644 --- a/packages/eslint-config-airbnb-base/.eslintrc +++ b/packages/eslint-config-airbnb-base/.eslintrc @@ -4,5 +4,5 @@ // disable requiring trailing commas because it might be nice to revert to // being JSON at some point, and I don't want to make big changes now. "comma-dangle": 0 - } + }, } diff --git a/packages/eslint-config-airbnb-base/index.js b/packages/eslint-config-airbnb-base/index.js index cc136737..4de657b0 100644 --- a/packages/eslint-config-airbnb-base/index.js +++ b/packages/eslint-config-airbnb-base/index.js @@ -9,10 +9,13 @@ module.exports = { './rules/imports', ].map(require.resolve), parserOptions: { - ecmaVersion: 2016, + ecmaVersion: 2017, sourceType: 'module', + ecmaFeatures: { + experimentalObjectRestSpread: true, + }, }, rules: { strict: 'error', - } + }, }; diff --git a/packages/eslint-config-airbnb-base/package.json b/packages/eslint-config-airbnb-base/package.json index c4ba9ead..6c630205 100644 --- a/packages/eslint-config-airbnb-base/package.json +++ b/packages/eslint-config-airbnb-base/package.json @@ -45,7 +45,7 @@ }, "homepage": "https://github.com/airbnb/javascript", "devDependencies": { - "babel-preset-airbnb": "^2.0.0", + "babel-preset-airbnb": "^2.1.0", "babel-tape-runner": "^2.0.1", "eslint": "^3.6.0", "eslint-find-rules": "^1.13.2", diff --git a/packages/eslint-config-airbnb-base/rules/best-practices.js b/packages/eslint-config-airbnb-base/rules/best-practices.js index d8d10b33..46fefab8 100644 --- a/packages/eslint-config-airbnb-base/rules/best-practices.js +++ b/packages/eslint-config-airbnb-base/rules/best-practices.js @@ -187,6 +187,10 @@ module.exports = { }, { property: '__defineSetter__', message: 'Please use Object.defineProperty instead.', + }, { + object: 'Object', + property: 'assign', + message: 'Please use the object spread operator (...) instead.', }], // disallow use of assignment in return statement diff --git a/packages/eslint-config-airbnb-base/test/.eslintrc b/packages/eslint-config-airbnb-base/test/.eslintrc index 7e22f26a..02ab3c48 100644 --- a/packages/eslint-config-airbnb-base/test/.eslintrc +++ b/packages/eslint-config-airbnb-base/test/.eslintrc @@ -1,7 +1,6 @@ { "rules": { - // disabled because I find it tedious to write tests while following this - // rule + // disabled because I find it tedious to write tests while following this rule "no-shadow": 0, // tests uses `t` for tape "id-length": [2, {"min": 2, "properties": "never", "exceptions": ["t"]}], diff --git a/packages/eslint-config-airbnb-base/test/test-base.js b/packages/eslint-config-airbnb-base/test/test-base.js index 3d500beb..7544a063 100644 --- a/packages/eslint-config-airbnb-base/test/test-base.js +++ b/packages/eslint-config-airbnb-base/test/test-base.js @@ -4,13 +4,15 @@ import test from 'tape'; import index from '../'; -const files = { index }; +const files = { ...{ index } }; // object spread is to test parsing fs.readdirSync(path.join(__dirname, '../rules')).forEach((name) => { files[name] = require(`../rules/${name}`); // eslint-disable-line global-require }); -Object.keys(files).forEach((name) => { +Object.keys(files).forEach(( + name, // trailing function comma is to test parsing +) => { const config = files[name]; test(`${name}: does not reference react`, (t) => { diff --git a/packages/eslint-config-airbnb/package.json b/packages/eslint-config-airbnb/package.json index e320fdf0..a5ede6ff 100644 --- a/packages/eslint-config-airbnb/package.json +++ b/packages/eslint-config-airbnb/package.json @@ -48,7 +48,7 @@ "eslint-config-airbnb-base": "^7.1.0" }, "devDependencies": { - "babel-preset-airbnb": "^2.0.0", + "babel-preset-airbnb": "^2.1.0", "babel-tape-runner": "^2.0.1", "eslint": "^3.6.0", "eslint-find-rules": "^1.13.2",