JavaScript coding specification (Chinese/Airbnb), javascriptair.pdf

Source: Internet
Author: User
Tags function calculator

JavaScript coding specification (Chinese/Airbnb), javascriptair.pdf

Airbnb is a company located in San Francisco, USA. This article is its internal JavaScript code specification, which is well written. on Github, there are 16,686 + Star, 3,080 + fork, front-end developers can refer.

Original article: https://github.com/airbnb/javascript

Note: I have deleted and modified some of the specifications according to my development habits.

Type
  • Original Value: equivalent to passing value

    • String
    • Number
    • Boolean
    • Null
    • Undefined
    var foo = 1,    bar = foo;bar = 9;console.log(foo, bar); // => 1, 9
  • Complex Type: equivalent to transferring reference

    • Object
    • Array
    • Function
    var foo = [1, 2],    bar = foo;bar[0] = 9;console.log(foo[0], bar[0]); // => 9, 9
Object
  • Create an object using the Literal Value

    // badvar item = new Object();// goodvar item = {};
  • Do not use reserved words as the key

    // badvar superman = {  class: 'superhero',  default: { clark: 'kent' },  private: true};// goodvar superman = {  klass: 'superhero',  defaults: { clark: 'kent' },  hidden: true};
Array
  • Create an array using the Literal Value

    // badvar items = new Array();// goodvar items = [];
  • If you do not know the length of the array, use push

    var someStack = [];// badsomeStack[someStack.length] = 'abracadabra';// goodsomeStack.push('abracadabra');
  • Use slice. jsPerf when you need to copy the Array

    var len = items.length,    itemsCopy = [],    i;// badfor (i = 0; i < len; i++) {  itemsCopy[i] = items[i];}// gooditemsCopy = items.slice();
  • Use slice to convert the objects of the class array into an array.

    function trigger() {  var args = Array.prototype.slice.call(arguments);  ...}
String
  • Use single quotes ''for strings''

    // badvar name = "Bob Parr";// goodvar name = 'Bob Parr';// badvar fullName = "Bob " + this.lastName;// goodvar fullName = 'Bob ' + this.lastName;
  • Character strings with more than 80 characters should use string connection to wrap

  • Note: long string connection may affect the performance if it is over-used. jsPerf & Discussion

    // badvar 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.';// badvar 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.';// goodvar 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.';
  • Use join instead of string join to construct a string during programming, especially IE: jsPerf.

    var items,    messages,    length, i;messages = [{    state: 'success',    message: 'This one worked.'},{    state: 'success',    message: 'This one worked as well.'},{    state: 'error',    message: 'This one did not work.'}];length = messages.length;// badfunction inbox(messages) {  items = '<ul>';  for (i = 0; i < length; i++) {    items += '<li>' + messages[i].message + '</li>';  }  return items + '</ul>';}// goodfunction inbox(messages) {  items = [];  for (i = 0; i < length; i++) {    items[i] = messages[i].message;  }  return '<ul><li>' + items.join('</li><li>') + '</li></ul>';}
Function
  • Function expression:

    // Anonymous function expression var anonymous = function () {return true ;}; // famous function expression var named = function named () {return true ;}; // call the function expression (function () {console. log ('Welcome to the Internet. please follow me. ');})();
  • Never declare a function in a non-function block and assign that function to a variable. The Browser allows you to do this, but the parsing is different.

  • Note: The ECMA-262 definition defines a block as a set of statements, and the function declaration is not a statement. Read the ECMA-262's explanation of this problem.

    // badif (currentUser) {  function test() {    console.log('Nope.');  }}// goodif (currentUser) {  var test = function test() {    console.log('Yup.');  };}
  • Do not name the parameter arguments, which will be beyond the arguments object passed in the function scope.

    // badfunction nope(name, options, arguments) {  // ...stuff...}// goodfunction yup(name, options, args) {  // ...stuff...}
Attribute
  • Brackets are used to access attributes using variables.

    var luke = {  jedi: true,  age: 28};function getProp(prop) {  return luke[prop];}var isJedi = getProp('jedi');
Variable
  • We always use var to declare variables. If we do not do this, global variables will be generated, so we should avoid contamination of the global namespace.

    // badsuperPower = new SuperPower();// goodvar superPower = new SuperPower();
  • Declare multiple variables using one var and a new line, and indent four spaces.

    // badvar items = getItems();var goSportsTeam = true;var dragonball = 'z';// goodvar items = getItems(),    goSportsTeam = true,    dragonball = 'z';
  • Finally, declare unassigned variables. It is useful when you want to reference previously assigned variables.

    // badvar i, len, dragonball,    items = getItems(),    goSportsTeam = true;// badvar i, items = getItems(),    dragonball,    goSportsTeam = true,    len;// goodvar items = getItems(),    goSportsTeam = true,    dragonball,    length,    i;
  • Declare variables at the top of the scope to avoid issues related to variable declaration and assignment.

    // badfunction() {  test();  console.log('doing stuff..');  //..other stuff..  var name = getName();  if (name === 'test') {    return false;  }  return name;}// goodfunction() {  var name = getName();  test();  console.log('doing stuff..');  //..other stuff..  if (name === 'test') {    return false;  }  return name;}// badfunction() {  var name = getName();  if (!arguments.length) {    return false;  }  return true;}// goodfunction() {  if (!arguments.length) {    return false;  }  var name = getName();  return true;}
Conditional expressions and equal signs
  • Use = and! = And! =.
  • The forced type conversion of conditional expressions follows the following rules:

    • The object is calculated as true.
    • Undefined is calculated as false.
    • Null is calculated as false.
    • The Boolean value is calculated as a Boolean value.
    • If the number is + 0,-0, or NaN, it is calculated as false. Otherwise, it is true.
    • If the string is an empty string '', the value is calculated as false; otherwise, the value is true.
    if ([0]) {  // true  // An array is an object, objects evaluate to true}
  • Use shortcuts.

    // badif (name !== '') {  // ...stuff...}// goodif (name) {  // ...stuff...}// badif (collection.length > 0) {  // ...stuff...}// goodif (collection.length) {  // ...stuff...}
  • Learn more about Truth Equality and JavaScript

Block
  • Use braces for all multiline Blocks

    // badif (test)  return false;// goodif (test) return false;// goodif (test) {  return false;}// badfunction() { return false; }// goodfunction() {  return false;}
Note
  • Use/**... */to annotate multiple rows, including descriptions, specified types, parameter values, and returned values.

    // bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunction make(tag) {  // ...stuff...  return element;}// good/** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */function make(tag) {  // ...stuff...  return element;}
  • Use // to comment on a single line, comment on a single line on the comment object, and leave a blank line before the comment.

    // badvar active = true;  // is current tab// good// is current tabvar active = true;// badfunction getType() {  console.log('fetching type...');  // set the default type to 'no type'  var type = this._type || 'no type';  return type;}// goodfunction getType() {  console.log('fetching type...');  // set the default type to 'no type'  var type = this._type || 'no type';  return type;}
  • If you have a problem that you need to review or if you suggest a solution that needs to be implemented, you need to add FIXME or TODO before your annotations to help others quickly understand.

    function Calculator() {  // FIXME: shouldn't use a global here  total = 0;  return this;}
    function Calculator() {  // TODO: total should be configurable by an options param  this.total = 0;  return this;}
Blank
  • Set tab to 4 spaces

    // badfunction() {∙∙var name;}// badfunction() {∙var name;}// goodfunction() {∙∙∙∙var name;}
  • Place a space in front of the braces

    // badfunction test(){  console.log('test');}// goodfunction test() {  console.log('test');}// baddog.set('attr',{  age: '1 year',  breed: 'Bernese Mountain Dog'});// gooddog.set('attr', {  age: '1 year',  breed: 'Bernese Mountain Dog'});
  • Use indentation for long method chains.

    // bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items')  .find('.selected')    .highlight()    .end()  .find('.open')    .updateCount();// badvar leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true)    .attr('width',  (radius + margin) * 2).append('svg:g')    .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')    .call(tron.led);// goodvar leds = stage.selectAll('.led')    .data(data)  .enter().append('svg:svg')    .class('led', true)    .attr('width',  (radius + margin) * 2)  .append('svg:g')    .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')    .call(tron.led);
Comma
  • Do not put commas in front

    // badvar once  , upon  , aTime;// goodvar once,    upon,    aTime;// badvar hero = {    firstName: 'Bob'  , lastName: 'Parr'  , heroName: 'Mr. Incredible'  , superPower: 'strength'};// goodvar hero = {  firstName: 'Bob',  lastName: 'Parr',  heroName: 'Mr. Incredible',  superPower: 'strength'};
  • Do not add extra commas, which may cause errors in IE. If you add one more comma, some ES3 implementations will calculate the length of multiple arrays.

    // badvar hero = {  firstName: 'Kevin',  lastName: 'Flynn',};var heroes = [  'Batman',  'Superman',];// goodvar hero = {  firstName: 'Kevin',  lastName: 'Flynn'};var heroes = [  'Batman',  'Superman'];
Semicolon
  • The statement must end with a plus sign.

    // bad(function() {  var name = 'Skywalker'  return name})()// good(function() {  var name = 'Skywalker';  return name;})();// good;(function() {  var name = 'Skywalker';  return name;})();
Type conversion
  • Type conversion is performed at the beginning of the statement.
  • String:

    //  => this.reviewScore = 9;// badvar totalScore = this.reviewScore + '';// goodvar totalScore = '' + this.reviewScore;// badvar totalScore = '' + this.reviewScore + ' total score';// goodvar totalScore = this.reviewScore + ' total score';
  • Use parseInt for a number and always carry the base number of type conversion.

    var inputValue = '4';// badvar val = new Number(inputValue);// badvar val = +inputValue;// badvar val = inputValue >> 0;// badvar val = parseInt(inputValue);// goodvar val = Number(inputValue);// goodvar val = parseInt(inputValue, 10);// good/** * parseInt was the reason my code was slow. * Bitshifting the String to coerce it to a * Number made it a lot faster. */var val = inputValue >> 0;
  • Boolean value:

    var age = 0;// badvar hasAge = new Boolean(age);// goodvar hasAge = Boolean(age);// goodvar hasAge = !!age;
Naming Conventions
  • Avoid a single character name and make your variable name descriptive.

    // badfunction q() {  // ...stuff...}// goodfunction query() {  // ..stuff..}
  • Use the hump naming rules when naming objects, functions, and instances

    // badvar OBJEcttsssss = {};var this_is_my_object = {};var this-is-my-object = {};function c() {};var u = new user({  name: 'Bob Parr'});// goodvar thisIsMyObject = {};function thisIsMyFunction() {};var user = new User({  name: 'Bob Parr'});
  • Use the upper case of the hump when naming constructors or classes

    // badfunction user(options) {  this.name = options.name;}var bad = new user({  name: 'nope'});// goodfunction User(options) {  this.name = options.name;}var good = new User({  name: 'yup'});
  • Add an underscore _

    // badthis.__firstName__ = 'Panda';this.firstName_ = 'Panda';// goodthis._firstName = 'Panda';
  • Use _ this when saving the reference to this.

    // badfunction() {  var self = this;  return function() {    console.log(self);  };}// badfunction() {  var that = this;  return function() {    console.log(that);  };}// goodfunction() {  var _this = this;  return function() {    console.log(_this);  };}
Accessors
  • Attribute accessors are not required
  • If you do have accessors, use getVal () and setVal ('hello ')

    // baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
  • If the attribute is a Boolean value, use isVal () or hasVal ()

    // badif (!dragon.age()) {  return false;}// goodif (!dragon.hasAge()) {  return false;}
  • You can create get () and set () functions, but they must be consistent.

    function Jedi(options) {  options || (options = {});  var lightsaber = options.lightsaber || 'blue';  this.set('lightsaber', lightsaber);}Jedi.prototype.set = function(key, val) {  this[key] = val;};Jedi.prototype.get = function(key) {  return this[key];};
Constructor
  • Instead of overwriting the prototype with a new object, overwriting the prototype will cause inheritance problems.

    function Jedi() {  console.log('new jedi');}// badJedi.prototype = {  fight: function fight() {    console.log('fighting');  },  block: function block() {    console.log('blocking');  }};// goodJedi.prototype.fight = function fight() {  console.log('fighting');};Jedi.prototype.block = function block() {  console.log('blocking');};
  • Methods can return this help method chain.

    // badJedi.prototype.jump = function() {  this.jumping = true;  return true;};Jedi.prototype.setHeight = function(height) {  this.height = height;};var luke = new Jedi();luke.jump(); // => trueluke.setHeight(20) // => undefined// goodJedi.prototype.jump = function() {  this.jumping = true;  return this;};Jedi.prototype.setHeight = function(height) {  this.height = height;  return this;};var luke = new Jedi();luke.jump()  .setHeight(20);
  • You can write a custom toString () method, but make sure it works normally without any side effects.

    function Jedi(options) {  options || (options = {});  this.name = options.name || 'no name';}Jedi.prototype.getName = function getName() {  return this.name;};Jedi.prototype.toString = function toString() {  return 'Jedi - ' + this.getName();};
Event
  • When attaching data to an event, a hash is passed in instead of the original value. This allows later contributors to add more data to the event data, instead of finding and updating the event processor.

    // bad$(this).trigger('listingUpdated', listing.id);...$(this).on('listingUpdated', function(e, listingId) {  // do something with listingId});

    Better:

    // good$(this).trigger('listingUpdated', { listingId : listing.id });...$(this).on('listingUpdated', function(e, data) {  // do something with data.listingId});
Module
  • The module should start! This ensures that if a faulty module forgets to include the last semicolon, no error will occur after merging.
  • This file should be named after the camper and in a folder of the same name, and the exported files must have the same name.
  • Add a method named noConflict () to set the exported module to a previous version and return it.
  • Always declare 'use strict 'At the top of the module ';

    // fancyInput/fancyInput.js!function(global) {  'use strict';  var previousFancyInput = global.FancyInput;  function FancyInput(options) {    this.options = options || {};  }  FancyInput.noConflict = function noConflict() {    global.FancyInput = previousFancyInput;    return FancyInput;  };  global.FancyInput = FancyInput;}(this);
JQuery
  • Cache jQuery queries

    // badfunction setSidebar() {  $('.sidebar').hide();  // ...stuff...  $('.sidebar').css({    'background-color': 'pink'  });}// goodfunction setSidebar() {  var $sidebar = $('.sidebar');  $sidebar.hide();  // ...stuff...  $sidebar.css({    'background-color': 'pink'  });}
  • $ ('. Sidebar ul') or $ ('. sidebar ul'), jsPerf

  • Use find to query jQuery objects with scopes

    // bad$('.sidebar', 'ul').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good (slower)$sidebar.find('ul');// good (faster)$($sidebar[0]).find('ul');

Via: https://github.com/adamlu/javascript-style-guide

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.