当前位置: 首页 > 工具软件 > Cupertino.js > 使用案例 >

JS实际开发项目中的编码小技巧

邢修明
2023-12-01

一.Github开源JavaScript风格规范

1.Airbnb JavaScript Style Guide()
2.JavaScript 风格指南

二.ES系列中30个常用的JavaScript简写技巧

30个常用的JavaScript简写技巧

三.JS逻辑优雅处理技巧

1.面试官问:如何拆解URL参数中queryString

入参格式参考:

const url = 'http://sample.com/?a=1&b=2&c=xx&d=2#hash';

出参格式参考:

const result = { a: '1', b: '2', c: 'xx', d: '' };
// 拆解URL参数中queryString,返回一个 key - value 形式的 object

解答一:正则

const queryString = (str)=>{
    const obj = {}
    str.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => (obj[k] = v))
    return obj
}

解答二:URLSearchParams

function getParams(u: URL) {
  const s = new URLSearchParams(u.search)
  const obj = {}
  s.forEach((v, k) => (obj[k] = v))
  return obj
}


const url = 'http://sample.com/?a=1&b=2&c=xx&d=2#hash';
getParams(new URL(url))

解答三:字符串分割

字符串分割拿到参数相关的字符串,再做类型转换

const dismantle = (url) => {
     const aimUrl = url.split('?').pop().split('#').shift().split('&');
     const res = {};
     aimUrl.forEach(item => {
          const [key, val] = item.split('=');
          res[key] = val;
     });
     return res;
}

面试官问:如何拆解URL参数中queryString

四.如何让你的代码变得干净优雅且可维护

(一).关于命名

1.使用有意义且易读的变量名(见名知义)

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

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

2.使用有意义的变量代替数组下标

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

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

3.变量名要简洁,不要附加无用信息

 
const Car = {
  carMake: "Honda",
  carModel: "Accord",
  carColor: "Blue"
};
function paintCar(car, color) {
  car.carColor = color;
}


const Car = {
  make: "Honda",
  model: "Accord",
  color: "Blue"
};
function paintCar(car, color) {
  car.color = color;
}

4.消除魔术字符串(用全大写的为常量)

 setTimeout(blastOff, 86400000);

 const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000;
setTimeout(blastOff, MILLISECONDS_PER_DAY);

5.使用默认参数替代短路运算符

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

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

(二).关于函数

1.一个函数只做一件事的好处在于易于理解、易于测试。

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

 
function emailActiveClients(clients) {
  clients.filter(isActiveClient).forEach(email);
}
function isActiveClient(client) {
  const clientRecord = database.lookup(client);
  return clientRecord.isActive();
}

---------------------分割线-----------------------

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

 
function createFile(name) {
  fs.create(name);
}
function createTempFile(name) {
  createFile(`./temp/${name}`);
}

2.函数名应该直接反映函数的作用


function addToDate(date, month) {
  // ...
}
const date = new Date();
// It's hard to tell from the function name what is added
addToDate(date, 1);

 
function addMonthToDate(month, date) {
  // ...
}
const date = new Date();
addMonthToDate(1, date);

3.函数参数不多于2个,如果有很多参数就利用object传递,并使用解构。
推荐使用解构的几个原因:
①看到函数签名可以立即了解有哪些参数
②解构能克隆传递到函数中的参数对象的值(浅克隆),有助于防止副作用.
③linter可以提示有哪些参数未被使用


function createMenu(title, body, buttonText, cancellable) {
  // ...
}
createMenu("Foo", "Bar", "Baz", true);

 
function createMenu({ title, body, buttonText, cancellable }) {
  // ...
}
createMenu({
  title: "Foo",
  body: "Bar",
  buttonText: "Baz",
  cancellable: true
});

4.一个函数的抽象层级不要太多,如果你的函数做了太多事,就需要把它拆分成多个函数.


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...
  });
}

 
function parseBetterJSAlternative(code) {
  const tokens = tokenize(code);
  const syntaxTree = parse(tokens);
  syntaxTree.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 parse(tokens) {
  const syntaxTree = [];
  tokens.forEach(token => {
    syntaxTree.push(/* ... */);
  });

  return syntaxTree;
}

5.减少重复代码

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);
  });
}

 
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);
  });
}

6.尽量使用纯函数 (函数式编程,not命令式编程)

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

 
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.reduce(
  (totalLines, output) => totalLines + output.linesOfCode,
  0
);

7.注意函数的副作用


const addItemToCart = (cart, item) => {
  cart.push({ item, date: Date.now() });
};

 
const addItemToCart = (cart, item) => {
  return [...cart, { item, date: Date.now() }];
};

8.不要过度优化
现代浏览器在运行时进行了大量的优化。很多时候,如果你再优化,那就是在浪费时间。


// 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++) {
  // ...
}

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

参考文章

1.让你的 JS 代码变得干净优雅且可维护
2.10 个必须知道的 JavaScript 技巧,让你成为更好的程序员
3.垃圾代码和优质代码的区别?
4.怎样写出可读性高的代码?
5.11个JavaScript代码重构最佳实践
6.一名合格前端工程师必备素质:代码整洁之道
7.到底如何写一个优雅的函数?来呀,看这里!
8.一名合格前端工程师必备素质:代码整洁之道

 类似资料: