美文网首页
javascript的原则

javascript的原则

作者: i5yue | 来源:发表于2018-08-14 22:54 被阅读53次

写在开头

最近在看原则一本书,发现生活中和工作中很多都是有规律有原则的,代码的世界里也一样,代码其实是写给人看的,机器是看不懂的,它只会按照人类设定的规则去运行。所以把代码写的规范一些,让更多的人看得懂,看得轻松,这就是一件很了不起的事情了,所以我搜集多方资料,为JavaScript也打造了一份属于它的原则,喜欢写JavaScript的朋友或者平时工作中用的多的朋友也可以看一下,相互学习。

Variables (变量)

简单四个字,见名思意。
Bad:

const yyyymmdstr = moment().format('YYYY/MM/DD');

Good:

const currentDate = moment().format('YYYY/MM/DD');

使用有意思的常量

Bad:

setTimeout(blastOff, 86400000);

Good:

const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);

Use explanatory variables

参数要用简洁
Bad:

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /[,\]+[,\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);

Good:

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /[,\]+[,\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

Avoid Mental Mapping

避免使用看不懂的词汇
Bad:

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
// Wait, what is l for again?
dispatch(l);
});

Good:

const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
dispatch(location);
});

Don't add unneeded context

如果对象名能够说明一些事,那么在值中就不要重复了。

Bad:

const Car = {
carMake: 'Honda',
carModel: 'Accord',
carColor: 'Blue'
};

function paintCar(car) {
car.carColor = 'Red';
}

Good:

const Car = {
make: 'Honda',
model: 'Accord',
color: 'Blue'
};

function paintCar(car) {
car.color = 'Red';
}

Use default arguments instead of short circuiting or conditionals

参数传递时,默认的参数传递最后如下。
Bad:

function createMicrobrewery(name) {
const breweryName = name || 'Hipster Brew Co.';
// ...
}

Good:

function createMicrobrewery(name = 'Hipster Brew Co.') {
// ...
}

Functions should do one thing

一个函数一次只专心做一件事
Bad:

function emailClients(clients) {
clients.forEach((client) => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}

Good:

function emailActiveClients(clients) {
clients
.filter(isActiveClient)
.forEach(email);
}

function isActiveClient(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}

Functions should only be one level of abstraction

复杂的方法应该抽离出独立的函数
Bad:

function parseBetterJSAlternative(code) {
const REGEXES = [
// ...
];

const statements = code.split(' ');
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
// ...
});
});

const ast = [];
tokens.forEach((token) => {
// lex...
});

ast.forEach((node) => {
// parse...
});
}

Good:

function parseBetterJSAlternative(code) {

const tokens = tokenize(code);
const ast = lexer(tokens);
ast.forEach((node) => {
// parse...
});
}

function tokenize(code) {
const REGEXES = [
// ...
];

const statements = code.split(' ');
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
tokens.push( /* ... */ );
});
});

return tokens;
}

function lexer(tokens) {
const ast = [];
tokens.forEach((token) => {
ast.push( /* ... */ );
});

return ast;
}

Remove duplicate code

去掉那些重复的代码,能够用一个函数解决的问题,不要拆分成两个

Bad:

function showDeveloperList(developers) {
developers.forEach((developer) => {
const expectedSalary = developer.calculateExpectedSalary();
const experience = developer.getExperience();
const githubLink = developer.getGithubLink();
const data = {
expectedSalary,
experience,
githubLink
};

render(data);

});
}

function showManagerList(managers) {
managers.forEach((manager) => {
const expectedSalary = manager.calculateExpectedSalary();
const experience = manager.getExperience();
const portfolio = manager.getMBAProjects();
const data = {
expectedSalary,
experience,
portfolio
};

render(data);

});
}

Good:

function showEmployeeList(employees) {
employees.forEach((employee) => {
const expectedSalary = employee.calculateExpectedSalary();
const experience = employee.getExperience();

const data = {
  expectedSalary,
  experience
};

switch (employee.type) {
  case 'manager':
    data.portfolio = employee.getMBAProjects();
    break;
  case 'developer':
    data.githubLink = employee.getGithubLink();
    break;
}

render(data);

});
}

Set default objects with Object.assign

尽量使用 Object.assign
Bad:

const menuConfig = {
title: null,
body: 'Bar',
buttonText: null,

cancellable: true
};

function createMenu(config) {
config.title = config.title || 'Foo';
config.body = config.body || 'Bar';
config.buttonText = config.buttonText || 'Baz';
config.cancellable = config.cancellable !== undefined ? config.cancellable : true;
}

createMenu(menuConfig);

Good:

const menuConfig = {
title: 'Order',
// User did not include 'body' key
buttonText: 'Send',
cancellable: true
};

function createMenu(config) {
config = Object.assign({
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
}, config);

// config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
// ...
}

createMenu(menuConfig);

Don't use flags as function parameters

别用参数来分离的函数
Bad:

function createFile(name, temp) {
if (temp) {
fs.create(./temp/${name});
} else {
fs.create(name);
}
}

Good:

function createFile(name) {
fs.create(name);
}

function createTempFile(name) {
createFile(./temp/${name});
}

Avoid Side Effects

避免写出副作用的函数
Bad:

let name = 'Ryan McDermott';

function splitIntoFirstAndLastName() {
name = name.split(' ');
}

splitIntoFirstAndLastName();

console.log(name); // ['Ryan', 'McDermott'];

Good:

function splitIntoFirstAndLastName(name) {
return name.split(' ');
}

const name = 'Ryan McDermott';
const newName = splitIntoFirstAndLastName(name);

console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];

Don't write to global functions

不要随意些全局的方法,最后是用calss来扩展
Bad:

Array.prototype.diff = function diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
};

Good:

class SuperArray extends Array {
diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
}
}

Favor functional programming over imperative programming

用函数式编程,少用命令式编程

Bad:

const programmerOutput = [
{
name: 'Uncle Bobby',
linesOfCode: 500
}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
];

let totalOutput = 0;

for (let i = 0; i < programmerOutput.length; i++) {
totalOutput += programmerOutput[i].linesOfCode;
}

Good:

const programmerOutput = [
{

name: 'Uncle Bobby',
linesOfCode: 500

}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
];

const totalOutput = programmerOutput
.map(output => output.linesOfCode)
.reduce((totalLines, lines) => totalLines + lines);

Encapsulate conditionals

该封装的时候旧的封装

Bad:

if (fsm.state === 'fetching' && isEmpty(listNode)) {
// ...
}

Good:

function shouldShowSpinner(fsm, listNode) {
return fsm.state === 'fetching' && isEmpty(listNode);
}

if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
// ...
}

Avoid negative conditionals

尽量使用肯定的条件

Bad:

function isDOMNodeNotPresent(node) {
// ...
}

if (!isDOMNodeNotPresent(node)) {
// ...
}

Good:

function isDOMNodePresent(node) {
// ...
}

if (isDOMNodePresent(node)) {
// ...
}

Avoid conditionals

一个函数只做一件事,哪怕很艰难,当你觉得麻烦的时候,那就是你再写复杂代码的时候

Bad:

class Airplane {
// ...
getCruisingAltitude() {
switch (this.type) {
case '777':
return this.getMaxAltitude() - this.getPassengerCount();
case 'Air Force One':
return this.getMaxAltitude();
case 'Cessna':
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
}

Good:

class Airplane {
// ...
}

class Boeing777 extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount();
}
}

class AirForceOne extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude();
}
}

class Cessna extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}

Don't over-optimize

现代浏览器其实做了很多优化,只是你未曾知道

Bad:

// On old browsers, each iteration with uncached list.length would be costly
// because of list.length recomputation. In modern browsers, this is optimized.
for (let i = 0, len = list.length; i < len; i++) {
// ...
}

Good:

for (let i = 0; i < list.length; i++) {
// ...
}

Remove dead code

删掉哪些没有用到注释的代码把

Bad:
function oldRequestModule(url) {
// ...
}

function newRequestModule(url) {
// ...
}

const req = newRequestModule;
inventoryTracker('apples', req, 'www.inventory-awesome.io');

Good:

function newRequestModule(url) {
// ...
}

const req = newRequestModule;
inventoryTracker('apples', req, 'www.inventory-awesome.io');

小结

以上主要是基础js代码编写中所需要注意的一些细节,看似都非常简蕴藏着能量非常巨大,平时的细节把握的好,工作中才不会产生很低级的错误。上面离打造干净整洁的代码还有很大一步。知识点得慢慢消化加以实践,我们还是小步慢慢来。

相关文章

  • javascript的原则

    写在开头 最近在看原则一本书,发现生活中和工作中很多都是有规律有原则的,代码的世界里也一样,代码其实是写给人看的,...

  • javascript的原则

    背景 这篇算是javascript的原则第二篇把,前一篇主要基础的讲解,这篇主要会讲一些数据结构和异常处理的讲解。...

  • JavaScript基础 - js基础

    1.就近原则2.具体性原则3.重要性原则 JavaScript = ECMAScript + BOM + DOM ...

  • javascript的原则三

    写在开头 平时在生活或者工作中那些原则看似简单平常,但是真的要日复一日的坚持下来,其实并非易事,难的事情并不可怕,...

  • Javascript开闭原则

    开闭原则的核心是:对扩展开放,对修改关闭 白话意思就是我们改变一个软件时(比如扩展其他功能),应该通过扩展的方式来...

  • JavaScript设计原则

    单一职责原则(SRP):一个对象(方法)只做一件事。 何时应该分离职责 SRP原则是所有原则中最简单也是最难正确运...

  • 《javascript+DOM编程艺术》读书笔记02

    2016-05-23 第五章 Javascript编程原则和良好习惯 1.JavaScript 使用window...

  • javascript 基本规范

    javascript 基本规范 注释 原则 As short as possible(如无必要,勿增注释):尽量提...

  • JavaScript 中的 SOLID 原则(五):“D”代表什

    本篇是SOLID原则的最后一篇,建议先阅读前四部分: JavaScript 中的 SOLID 原则(一):“S”代...

  • Apache架构师总结的30条设计原则

    Apache架构师总结的30条设计原则! Srinath [架构艺术](javascript:void(0);) ...

网友评论

      本文标题:javascript的原则

      本文链接:https://www.haomeiwen.com/subject/icppbftx.html