热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AirbnbJavaScript编码作风指南(2018年最新版)

AirbnbJavaScript编码作风指南(2018年最新版)接见此原文地点:http:galaxyteam.pubdidi-fe…别的迎接接见我们保护的https:www.th
Airbnb Javascript 编码作风指南(2018年最新版)

接见此原文地点:
http://galaxyteam.pub/didi-fe…

别的迎接接见我们保护的
https://www.threejs.online 中文站
(迎接Star!)

本文译者:滴滴出行上海前端(FE)团队杨永乐同砚

范例

  1. 基础范例:直接存取

    • string
    • number
    • boolean
    • null
    • undefined
    • symbol

    const foo = 1;
    let bar = foo;
    bar = 9;
    console.log(foo, bar); // => 1, 9

    • symbol 范例不能完整polyfilled,所以请郑重运用
  2. 庞杂范例: 经由过程援用的体式格局存取

    • object
    • array
    • function

    const foo = [1, 2];
    const bar = foo;
    bar[0] = 9;
    console.log(foo[0], bar[0]); // => 9, 9

援用

  1. 运用const说明援用范例,防止运用var。eslint 设置:prefer-const,no-const-assign

    为何?这能确保你没法对援用从新赋值,也不会致使涌现 bug 或难以明白。

    // bad
    var a = 1;
    var b = 2;
    // good
    const a = 1;
    const b = 2;

  2. 假如必需对援用范例从新赋值,运用let而非var。eslint设置:no-var jscs: disallowVar

    为何?比拟于
    var函数作用域,
    let块级作用域更轻易明白

    // bad
    var count = 1;
    if (true) {
    count += 1;
    }
    // good, use the let.
    let count = 1;
    if (true) {
    count += 1;
    }

  3. 注重letconst都是块级作用域

    // const and let only exist in the blocks they are defined in.
    {
    let a = 1;
    const b = 1;
    }
    console.log(a); // ReferenceError
    console.log(b); // ReferenceError

对象

  1. 运用字面值建立对象。eslint: no-new-object

    // bad
    const item = new Object();
    // good
    const item = {};

  2. 建立对象的动态属性时,运用盘算属性

    为何?如许可以在一个处所定义对象一切的属性

    function getKey(k) {
    return `a key named ${k}`;
    }
    // bad
    const obj = {
    id: 5,
    name: 'San Francisco',
    };
    obj[getKey('enabled')] = true;
    // good
    const obj = {
    id: 5,

[getKey('enabled')]: true,
};
```

  1. 运用对象要领的简写情势。 eslint: object-shorthand jscs: requireEnhancedObjectLiterals

    为何?要领定义简约清楚

    // bad
    const atom = {
    value: 1,
    addValue: function (value) {
    return atom.value + value;
    },
    };
    // good
    const atom = {
    value: 1,
    addValue(value) {
    return atom.value + value;
    },
    };

  2. 运用属性值简写情势。eslint: object-shorthand jscs: [requireEnhancedObjectLiterals]

    为何?誊写越发简约,更有描述性。

    const lukeSkywalker = 'Luke Skywalker';
    // bad
    const obj = {
    lukeSkywalker: lukeSkywalker,
    };
    // good
    const obj = {
    lukeSkywalker,
    };

  3. 对象声明时分类简写和非简写的属性名。

    为何?更清楚的相识哪些属性是简写的。

    const anakinSkywalker = 'Anakin Skywalker';
    const lukeSkywalker = 'Luke Skywalker';
    // bad
    const obj = {
    episodeOne: 1,
    twoJediWalkIntoACantina: 2,
    lukeSkywalker,
    episodeThree: 3,
    mayTheFourth: 4,
    anakinSkywalker,
    };
    // good
    const obj = {
    lukeSkywalker,
    anakinSkywalker,
    episodeOne: 1,
    twoJediWalkIntoACantina: 2,
    episodeThree: 3,
    mayTheFourth: 4,
    };

  4. 只要对那些不合法的属性名标识符增添引号。eslint: quote-props jscs: disallowQuotedKeysInObjects

    为何?对象属性更直观,可读性强。可以代码高亮显现,同时关于大多数的js引擎更轻易优化代码。

    // bad
    const bad = {
    'foo': 3,
    'bar': 4,
    'data-blah': 5,
    };
    // good
    const good = {
    foo: 3,
    bar: 4,
    'data-blah': 5,
    };

  5. 不要直接运用Object.prototype上的要领,比方hasOwnProperty, propertyIsEnumerable, 和 isPrototypeOf

    为何?这些要领能够受对象的其他属性影响。比方
    { hasOwnProperty: false } 也许 对象多是null(
    Object.create(null))

    // bad
    console.log(object.hasOwnProperty(key));
    const object = Object.create(null);
    obj.hasOwnProperty(key) // Uncaught TypeError: obj.hasOwnProperty is not a function
    // good
    console.log(Object.prototype.hasOwnProperty.call(object, key));
    // best
    const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
    /* or */
    import has from 'has'; // https://www.npmjs.com/package/has
    // ...
    console.log(has.call(object, key));

  6. 浅拷贝对象时引荐运用对象睁开操纵(object spread operator)而不是Object.assign。运用对象盈余操纵符(object rest operator)猎取对象中盈余的属性。

    为何?
    Object.assign运用不当会修正原对象

    // 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 }

数组

  1. 运用字面量声明数组。eslint: no-array-constructor

    // bad
    const items = new Array();
    // good
    const items = [];

  2. 向数组增添元素时,运用Arrary#push替换直接赋值。

    const someStack = [];
    // bad
    someStack[someStack.length] = 'abracadabra';
    // good
    someStack.push('abracadabra');

  3. 运用数组睁开操纵符...拷贝数组

    // bad
    const len = items.length;
    const itemsCopy = [];
    let i;
    for (i = 0; i itemsCopy[i] = items[i];
    }
    // good
    const itemsCopy = [...items];

  4. 将类数组对象(array-like)转换成数组时,运用...而不是Array.from

    const foo = document.querySelectorAll('.foo');
    // good
    const nodes = Array.from(foo);
    // best
    const nodes = [...foo];

  5. 当须要对可遍历对象举行map操纵时,运用Array.from而不是睁开操纵符...,防止新建一个暂时数组。

    // bad
    const baz = [...foo].map(bar);
    // good
    const baz = Array.from(foo, bar);

  6. 数组要领回调须要有返回值。假如函数体比较简单,可以直接用表达式,省略return语句。 eslint: array-callback-return

    // good
    [1, 2, 3].map((x) => {
    const y = x + 1;
    return x * y;
    });
    // good
    [1, 2, 3].map(x => x + 1);
    // bad - no returned value means `memo` becomes undefined after the first iteration
    [[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
    const flatten = memo.concat(item);
    memo[index] = flatten;
    });
    // good
    [[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
    const flatten = memo.concat(item);
    memo[index] = flatten;
    return flatten;
    });
    // bad
    inbox.filter((msg) => {
    const { subject, author } = msg;
    if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
    } else {
    return false;
    }
    });
    // good
    inbox.filter((msg) => {
    const { subject, author } = msg;
    if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
    }
    return false;
    });

  7. 假如数组有多行,请在翻开和封闭数组括号之前运用换行符

    为何? 更具有可读性

    // bad
    const arr = [
    [0, 1], [2, 3], [4, 5],
    ];
    const objectInArray = [{
    id: 1,
    }, {
    id: 2,
    }];
    const numberInArray = [
    1, 2,
    ];
    // good
    const arr = [[0, 1], [2, 3], [4, 5]];
    const objectInArray = [
    {
    id: 1,
    },
    {
    id: 2,
    },
    ];
    const numberInArray = [
    1,
    2,
    ];

解构

  1. 接见和运用对象的多个属性时用对象解构操纵。eslint: prefer-destructuring jscs: requireObjectDestructuring

    为何?解构可以防止为这些属性建立暂时援用。

    // bad
    function getFullName(user) {
    const firstName = user.firstName;
    const lastName = user.lastName;
    return `${firstName} ${lastName}`;
    }
    // good
    function getFullName(user) {
    const { firstName, lastName } = user;
    return `${firstName} ${lastName}`;
    }
    // best
    function getFullName({ firstName, lastName }) {
    return `${firstName} ${lastName}`;
    }

  2. 运用数组解构。eslint: prefer-destructuring jscs: requireArrayDestructuring

    const arr = [1, 2, 3, 4];
    // bad
    const first = arr[0];
    const secOnd= arr[1];
    // good
    const [first, second] = arr;

  3. 运用对象解构来完成多个返回值,而不是数组解构。jscs: disallowArrayDestructuringReturn

    为何?你可以随时为返回值新增属性而不必体贴属性的递次。

    // bad
    function processInput(input) {
    // then a miracle occurs
    return [left, right, top, bottom];
    }
    // 挪用者须要注重返回值中对象的递次
    const [left, __, top] = processInput(input);
    // good
    function processInput(input) {
    // then a miracle occurs
    return { left, right, top, bottom };
    }
    // 挪用者只须要运用它须要的对象
    const { left, top } = processInput(input);

字符串

  1. 字符串运用单引号。eslint: quotes jscs: validateQuoteMarks

    // bad
    const name = "Capt. Janeway";
    // bad - 当须要插值也许换行时才运用模板笔墨
    const name = `Capt. Janeway`;
    // good
    const name = 'Capt. Janeway';

  2. 不凌驾100个字符的字符串不应当运用连接符也许换行誊写。

    为何?换行的字符串不好浏览,而且不方便搜刮代码。

    // bad
    const errorMessage = 'This is a super long error that was thrown because \
    of Batman. When you stop to think about how Batman had anything to do \
    with this, you would get nowhere \
    fast.';
    // bad
    const errorMessage = 'This is a super long error that was thrown because ' +
    'of Batman. When you stop to think about how Batman had anything to do ' +
    'with this, you would get nowhere fast.';
    // good
    const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';

  3. 以编程体式格局构建字符串时,运用模板字符串而不是连接符。eslint: prefer-template template-curly-spacing jscs: requireTemplateStrings

    为何?模板字符串更加简约,更具可读性。

    // bad
    function sayHi(name) {
    return 'How are you, ' + name + '?';
    }
    // bad
    function sayHi(name) {
    return ['How are you, ', name, '?'].join();
    }
    // bad
    function sayHi(name) {
    return `How are you, ${ name }?`;
    }
    // good
    function sayHi(name) {
    return `How are you, ${name}?`;
    }

  4. 永久不要在字符串上运用eval()要领,它有太多的题目。eslint: no-eval
  5. 不要过量的转义字符串。eslint: no-useless-escape

    为何?反斜杠影响代码可读性,只要在必要的时刻才运用。

    // bad
    const foo = '\'this\' \i\s \"quoted\"';
    // good
    const foo = '\'this\' is "quoted"';
    const foo = `my name is '${name}'`;

函数

  1. 运用定名函数表达式而不是函数声明。eslint: func-style jscs: disallowFunctionDeclarations

    为何?函数声明会被提早。这意味着很能够在函数定义前援用该函数,然则不会报错。这不利于代码的可读性和可保护性。假如你发明一个函数定义的很大很庞杂,以至于阻碍了相识文件中的其他内容,那末是时刻把这个函数提取到本身的模块中去了!不要遗忘显现指定表达式的称号,只管它能从变量名中被揣摸出来(当代浏览器也许编译器(如Babel)支撑)。这能让毛病的挪用栈更清楚。(
    议论)

    // bad
    function foo() {
    // ...
    }
    // bad
    const foo = function () {
    // ...
    };
    // good
    // 函数名和变量援用名差别
    const short = function longUniqueMoreDescriptiveLexicalFoo() {
    // ...
    };

    // Is it worse
    const sum = function(a, b) {
    return a + b;
    };
    // than this?
    const my_sum = function sum(a, b) {
    return a + b;
    };

    第一个函数没有
    .name属性,在debugging过程当中,它会是一个匿名函数。第二个函数有名字为
    sum,你可以检索到它,调试过程当中可以疾速定位。

    运用banel 和babel-preset-env设置,const foo = () => {}会转换成var foo = function foo () {},而且从Node v6最先,const foo = () => {}中的foo 也有.name。所以它不再是匿名函数。(函数名字揣摸)

  2. 用圆括号包裹马上实行函数表达式(IIFE)。eslint: wrap-iife jscs: requireParenthesesAroundIIFE

    为何? 马上实行函数表达式是单一实行单位-运用圆括号包裹挪用,简约明了的示意了这一点。请注重,在通用的模块中,你险些用不到IIFE。

    // immediately-invoked function expression (IIFE)
    (function () {
    console.log('Welcome to the Internet. Please follow me.');
    }());

  3. 永久不要在一个非函数代码块(if、while 等)中声明一个函数,把谁人函数赋给一个变量。浏览器许可你这么做,但它们的剖析表现不一致。eslint: no-loop-func
  4. 注重:ECMA-262把block定义为一组语句。然则函数声明不是语句。

    // bad
    if (currentUser) {
    function test() {
    console.log('Nope.');
    }
    }
    // good
    let test;
    if (currentUser) {
    test = () => {
    console.log('Yup.');
    };
    }

  5. 永久不要把参数定名为arguments。这将庖代本来函数作用域内的 arguments对象。

    // bad
    function foo(name, options, arguments) {
    // ...
    }
    // good
    function foo(name, options, args) {
    // ...
    }

  6. 不要运用arguments。可以挑选 rest 语法 ... 替换。

    为何?运用
    ... 能明白你要传入的参数。别的 rest 参数是一个真正的数组,而
    arguments 是一个类数组。

    // bad
    function concatenateAll() {
    const args = Array.prototype.slice.call(arguments);
    return args.join('');
    }
    // good
    function concatenateAll(...args) {
    return args.join('');
    }

  7. 运用函数默许参数指定默许值,而不是用一个可变的函数参数

    // really bad
    function handleThings(opts) {
    // 不!我们不应当转变函数参数
    // 更蹩脚的是: 假如 opts 是 falsy (为''也许是false), 它依然会被赋值为对象,然则这能够会激发bug
    opts = opts || {};
    // ...
    }
    // still bad
    function handleThings(opts) {
    if (opts === void 0) {
    opts = {};
    }
    // ...
    }
    // good
    function handleThings(opts = {}) {
    // ...
    }

8.运用函数参数默许值的时防止副作用。

> 为何?如许的写法会让人疑心。
```Javascript
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
```

  1. 参数默许值放在函数参数列表的末了。

    // bad
    function handleThings(opts = {}, name) {
    // ...
    }
    // good
    function handleThings(name, opts = {}) {
    // ...
    }

  2. 不要运用Function组织器建立函数。 eslint: no-new-func

    为何?经由过程这类体式格局建立的函数和运用
    eval()相似,会带来不确定的题目

    // bad
    var add = new Function('a', 'b', 'return a + b');
    // still bad
    var subtract = Function('a', 'b', 'return a - b');

  3. 函数名双方留白。eslint: space-before-function-paren [space-before-blocks]

    为何?坚持代码一致性,当你增添也许删除名字时不须要分外增减空格。

    // bad
    const f = function(){};
    const g = function (){};
    const h = function() {};
    // good
    const x = function () {};
    const y = function a() {};

  4. 不要修正参数。 eslint: no-param-reassign

    为何?操纵参数对象会在原始挪用方中致使不可预知的变量副作用。

    // bad
    function f1(obj) {
    obj.key = 1;
    }
    // good
    function f2(obj) {
    const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
    }

  5. 不要给参数赋值。eslint: no-param-reassign

    为何?从新分配参数能够会致使不测的行动,特别是在接见参数对象时。 它也能够致使优化题目,特别是在V8中。

    // bad
    function f1(a) {
    a = 1;
    // ...
    }
    function f2(a) {
    if (!a) { a = 1; }
    // ...
    }
    // good
    function f3(a) {
    const b = a || 1;
    // ...
    }
    function f4(a = 1) {
    // ...
    }

  6. 运用睁开操纵符...挪用可变参数函数。eslint: prefer-spread

    为何?它更简约,你不须要供应上下文,而且组合运用
    new
    apply不轻易。

    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);
    // bad
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
    // good
    new Date(...[2016, 8, 5]);

  7. 带有多行函数署名或挪用的函数应当像本指南中的其他多行列表一样缩进:每行中包括一项,末了一个项目带有逗号。

    // bad
    function foo(bar,
    baz,
    quux) {
    // ...
    }
    // good
    function foo(
    bar,
    baz,
    quux,
    ) {
    // ...
    }
    // bad
    console.log(foo,
    bar,
    baz);
    // good
    console.log(
    foo,
    bar,
    baz,
    );

箭头函数

  1. 当你必须要运用匿名函数(如在通报内联回调时),请运用箭头函数。eslint: prefer-arrow-callback, arrow-spacing jscs: requireArrowFunctions

    为何?因为箭头函数制造了新的一个 this 实行环境,一般情况下都能满足你的需求,而且如许的写法更加简约。(参考
    Arrow functions – Javascript | MDN )

    为何不?假如你有一个相称庞杂的函数,你也许可以把逻辑部份转移到一个函数声明上。

    // bad
    [1, 2, 3].map(function (x) {
    const y = x + 1;
    return x * y;
    });
    // good
    [1, 2, 3].map((x) => {
    const y = x + 1;
    return x * y;
    });

  2. 假如一个函数适合用一行写出而且只要一个参数,那就把花括号、圆括号和 return 都省略掉。假如不是,那就不要省略。eslint: arrow-parens, arrow-body-style jscs: disallowParenthesesAroundArrowParam, requireShorthandArrowFunctions

    为何?这是一个很好用的语法糖。在链式挪用中可读性很高。

    // bad
    [1, 2, 3].map(number => {
    const nextNumber = number + 1;
    `A string containing the ${nextNumber}.`;
    });
    // good
    [1, 2, 3].map(number => `A string containing the ${number}.`);
    // good
    [1, 2, 3].map((number) => {
    const nextNumber = number + 1;
    return `A string containing the ${nextNumber}.`;
    });
    // good

[index]: number,
}));
// No implicit return with side effects
function foo(callback) {
const val = callback();
if (val === true) {
// Do something if callback returns true
}
}
let bool = false;
// bad
foo(() => bool = true);
// good
foo(() => {
bool = true;
});
```

  1. 假如表达式太长须要多行示意,请将其包括在括号中,增添可读性。

    为何?它能消灭的标识函数的最先和完毕位置。

    // bad
    ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
    httpMagicObjectWithAVeryLongName,
    httpMethod,
    )
    );
    // good
    ['get', 'post', 'put'].map(httpMethod => (
    Object.prototype.hasOwnProperty.call(
    httpMagicObjectWithAVeryLongName,
    httpMethod,
    )
    ));

  2. 假如函数只要一个参数而且函数体没有运用花括号,那就省略括号。不然,为了坚持清楚一致性,总在参数四周加上括号。老是运用括号也是可以接收的,在这类情况下运用eslint的 “always” option 也许不要在jscs中引入 disallowParenthesesAroundArrowParam。eslint: arrow-parens jscs: disallowParenthesesAroundArrowParam

    为何? 不那末杂沓,可读性强。

    // bad
    [1, 2, 3].map((x) => x * x);
    // good
    [1, 2, 3].map(x => x * x);
    // good
    [1, 2, 3].map(number => (
    `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
    ));
    // bad
    [1, 2, 3].map(x => {
    const y = x + 1;
    return x * y;
    });
    // good
    [1, 2, 3].map((x) => {
    const y = x + 1;
    return x * y;
    });

  3. 防止箭头函数语法(=>)和比较运算符(<=,=>)一同运用时带来的疑心。

    // bad
    const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
    // bad
    const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
    // good
    const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
    // good
    const itemHeight = (item) => {
    const { height, largeSize, smallSize } = item;
    return height > 256 ? largeSize : smallSize;
    };

类 & 组织函数

  1. 老是运用class。防止直接操纵prototype

    为何?
    class语法更简约更易于明白。

    // bad
    function Queue(cOntents= []) {
    this.queue = [...contents];
    }
    Queue.prototype.pop = function () {
    const value = this.queue[0];
    this.queue.splice(0, 1);
    return value;
    };
    // good
    class Queue {
    constructor(cOntents= []) {
    this.queue = [...contents];
    }
    pop() {
    const value = this.queue[0];
    this.queue.splice(0, 1);
    return value;
    }
    }

  2. 运用extends继续。

    为何? 因为 extends 是一个内建的原型继续要领而且不会损坏 instanceof。

    // bad
    const inherits = require('inherits');
    function PeekableQueue(contents) {
    Queue.apply(this, contents);
    }
    inherits(PeekableQueue, Queue);
    PeekableQueue.prototype.peek = function () {
    return this.queue[0];
    };
    // good
    class PeekableQueue extends Queue {
    peek() {
    return this.queue[0];
    }
    }

  3. 要领可以返回 this 来协助链式挪用。

    // bad
    Jedi.prototype.jump = function () {
    this.jumping = true;
    return true;
    };
    Jedi.prototype.setHeight = function (height) {
    this.height = height;
    };
    const luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20); // => undefined
    // good
    class Jedi {
    jump() {
    this.jumping = true;
    return this;
    }
    setHeight(height) {
    this.height = height;
    return this;
    }
    }
    const luke = new Jedi();
    luke.jump()
    .setHeight(20);

  4. 可以写一个自定义的 toString() 要领,但要确保它能一般运转而且不会引发副作用。

    class Jedi {
    constructor(optiOns= {}) {
    this.name = options.name || 'no name';
    }
    getName() {
    return this.name;
    }
    toString() {
    return `Jedi - ${this.getName()}`;
    }
    }

  5. 类有默许组织器。一个空的组织函数也许只是重载父类组织函数是不必要的。eslint: no-useless-constructor

    // bad
    class Jedi {
    constructor() {}
    getName() {
    return this.name;
    }
    }
    // bad
    class Rey extends Jedi {
    constructor(...args) {
    super(...args);
    }
    }
    // good
    class Rey extends Jedi {
    constructor(...args) {
    super(...args);
    this.name = 'Rey';
    }
    }

  6. 防止反复的类成员。eslint: no-dupe-class-members

    为何?反复的类成员声明中只要末了一个见效-反复的声明肯定是一个毛病。

    // bad
    class Foo {
    bar() { return 1; }
    bar() { return 2; }
    }
    // good
    class Foo {
    bar() { return 1; }
    }
    // good
    class Foo {
    bar() { return 2; }
    }

模块

  1. 老是运用模组 (import/export) 而不是其他非标准模块体系。你可以编译为你喜好的模块体系。

    为何?模块是将来,让我们最先迈向将来吧。

    // bad
    const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    module.exports = AirbnbStyleGuide.es6;
    // ok
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    export default AirbnbStyleGuide.es6;
    // best
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

  2. 不要运用通配符 import

    为何?如许确保只要一个默许的export

    // bad
    import * as AirbnbStyleGuide from './AirbnbStyleGuide';
    // good
    import AirbnbStyleGuide from './AirbnbStyleGuide';

  3. 不要直接从importexport

    为何?虽然一行代码简约明了,但让
    import
    export 各司其职让事变能坚持一致。

    // bad
    // filename es6.js
    export { es6 as default } from './AirbnbStyleGuide';
    // good
    // filename es6.js
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

  4. 同一个途径只运用一次import。eslint: no-duplicate-imports

    为何?雷同途径有多个
    import会致使代码难以保护。

    // bad
    import foo from 'foo';
    // … some other imports … //
    import { named1, named2 } from 'foo';
    // good
    import foo, { named1, named2 } from 'foo';
    // good
    import foo, {
    named1,
    named2,
    } from 'foo';

  5. 不要export可变的绑定。 eslint: import/no-mutable-exports

    为何?防止不确定的可变量,特别是
    export可变的绑定。假如某些特殊情况须要运用这类场景,一般应当
    export常量援用。

    // bad
    let foo = 3;
    export { foo };
    // good
    const foo = 3;
    export { foo };

  6. 模块中只要单个export,最好运用default export 。 eslint: import/prefer-default-export

    为何?一个文件最好只做一件事,如许更具有可读性和可保护性。

    // bad
    export function foo() {}
    // good
    export default function foo() {}

  7. 将一切的import语句放在文件的顶部。eslint: import/first

    为何?因为
    imports会被提拔,最好坚持它们在顶部以防涌现不可预期的行动。

    // bad
    import foo from 'foo';
    foo.init();
    import bar from 'bar';
    // good
    import foo from 'foo';
    import bar from 'bar';
    foo.init();

  8. 多行import应当和多行数组和对象一样有缩进。

    为何?花括号须要遵照与指南中的每一个其他花括号雷同的缩进划定规矩,末端的逗号也一样。

    // bad
    import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
    // good
    import {
    longNameA,
    longNameB,
    longNameC,
    longNameD,
    longNameE,
    } from 'path';

  9. 制止在模块导入语句中运用Webpack加载器语法。eslint: import/no-webpack-loader-syntax

    为何?在
    import中运用webpack 语法会将代码耦合进bundler中。引荐在
    webpack.config.js中设置loader 划定规矩。

    // bad
    import fooSass from 'css!sass!foo.scss';
    import barCss from 'style!css!bar.css';
    // good
    import fooSass from 'foo.scss';
    import barCss from 'bar.css';


推荐阅读
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 前端监控数据网络(要求阻拦)
    所谓web,纵然你我素未谋面,便知志趣相投;深居简出,亦知天下之大。01—为何阻拦要求如今的web运用,大都是经由过程要求(http)去猎取资本,拿到资本后再显现给用户,一个页面中 ... [详细]
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文讨论了在使用PHP cURL发送POST请求时,请求体在node.js中没有定义的问题。作者尝试了多种解决方案,但仍然无法解决该问题。同时提供了当前PHP代码示例。 ... [详细]
  • HowcanIaligntwoinline-blockssothatoneisleftandtheotherisrightonthesameline?Whyi ... [详细]
author-avatar
michael
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有