摘要:在作用域頂部聲明變量,避免變量聲明和賦值引起的相關問題。分號語句結束一定要加分號類型轉換在語句的開始執(zhí)行類型轉換字符串對數(shù)字使用并且總是帶上類型轉換的基數(shù)布爾值命名約定避免單個字符名,讓你的變量名有描述意義。
JavaScript規(guī)范 內容列表原文:https://github.com/airbnb/javascript
類型
對象
數(shù)組
字符串
函數(shù)
屬性
變量
條件表達式和等號
塊
注釋
空白
逗號
分號
類型轉換
命名約定
存取器
構造器
事件
模塊
jQuery
ES5 兼容性
性能
資源
哪些人在使用
翻譯
JavaScript風格指南
貢獻者
許可
類型
原始值: 相當于傳值
string
number
boolean
null
undefined
var foo = 1, bar = foo; bar = 9; console.log(foo, bar); // => 1, 9
復雜類型: 相當于傳引用
object
array
function
var foo = [1, 2], bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9
**[[?]](#TOC)**對象
使用字面值創(chuàng)建對象
// bad var item = new Object(); // good var item = {};
不要使用保留字 reserved words 作為鍵
// bad var superman = { class: "superhero", default: { clark: "kent" }, private: true }; // good var superman = { klass: "superhero", defaults: { clark: "kent" }, hidden: true };
**[[?]](#TOC)**數(shù)組
使用字面值創(chuàng)建數(shù)組
// bad var items = new Array(); // good var items = [];
如果你不知道數(shù)組的長度,使用push
var someStack = []; // bad someStack[someStack.length] = "abracadabra"; // good someStack.push("abracadabra");
當你需要拷貝數(shù)組時使用slice. jsPerf
var len = items.length, itemsCopy = [], i; // bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good itemsCopy = items.slice();
使用slice將類數(shù)組的對象轉成數(shù)組.
function trigger() { var args = Array.prototype.slice.call(arguments); ... }
**[[?]](#TOC)**字符串
對字符串使用單引號 ""
// bad var name = "Bob Parr"; // good var name = "Bob Parr"; // bad var fullName = "Bob " + this.lastName; // good var fullName = "Bob " + this.lastName;
超過80個字符的字符串應該使用字符串連接換行
注: 如果過度使用,長字符串連接可能會對性能有影響. jsPerf & Discussion
// bad var 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 var 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 var 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.";
編程時使用join而不是字符串連接來構建字符串,特別是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; // bad function inbox(messages) { items = "
**[[?]](#TOC)**函數(shù)
函數(shù)表達式:
// 匿名函數(shù)表達式 var anonymous = function() { return true; }; // 有名函數(shù)表達式 var named = function named() { return true; }; // 立即調用函數(shù)表達式 (function() { console.log("Welcome to the Internet. Please follow me."); })();
絕對不要在一個非函數(shù)塊里聲明一個函數(shù),把那個函數(shù)賦給一個變量。瀏覽器允許你這么做,但是它們解析不同。
注: ECMA-262定義把塊定義為一組語句,函數(shù)聲明不是一個語句。閱讀ECMA-262對這個問題的說明.
// bad if (currentUser) { function test() { console.log("Nope."); } } // good if (currentUser) { var test = function test() { console.log("Yup."); }; }
絕對不要把參數(shù)命名為 arguments, 這將會逾越函數(shù)作用域內傳過來的 arguments 對象.
// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }
**[[?]](#TOC)**屬性
當使用變量訪問屬性時使用中括號.
var luke = { jedi: true, age: 28 }; function getProp(prop) { return luke[prop]; } var isJedi = getProp("jedi");
**[[?]](#TOC)**變量
總是使用 var 來聲明變量,如果不這么做將導致產生全局變量,我們要避免污染全局命名空間。
// bad superPower = new SuperPower(); // good var superPower = new SuperPower();
使用一個 var 以及新行聲明多個變量,縮進4個空格。
// bad var items = getItems(); var goSportsTeam = true; var dragonball = "z"; // good var items = getItems(), goSportsTeam = true, dragonball = "z";
最后再聲明未賦值的變量,當你想引用之前已賦值變量的時候很有用。
// bad var i, len, dragonball, items = getItems(), goSportsTeam = true; // bad var i, items = getItems(), dragonball, goSportsTeam = true, len; // good var items = getItems(), goSportsTeam = true, dragonball, length, i;
在作用域頂部聲明變量,避免變量聲明和賦值引起的相關問題。
// bad function() { test(); console.log("doing stuff.."); //..other stuff.. var name = getName(); if (name === "test") { return false; } return name; } // good function() { var name = getName(); test(); console.log("doing stuff.."); //..other stuff.. if (name === "test") { return false; } return name; } // bad function() { var name = getName(); if (!arguments.length) { return false; } return true; } // good function() { if (!arguments.length) { return false; } var name = getName(); return true; }
**[[?]](#TOC)**條件表達式和等號
適當使用 === 和 !== 以及 == 和 !=.
條件表達式的強制類型轉換遵循以下規(guī)則:
對象 被計算為 true
Undefined 被計算為 false
Null 被計算為 false
布爾值 被計算為 布爾的值
數(shù)字 如果是 +0, -0, or NaN 被計算為 false , 否則為 true
字符串 如果是空字符串 "" 則被計算為 false, 否則為 true
if ([0]) { // true // An array is an object, objects evaluate to true }
使用快捷方式.
// bad if (name !== "") { // ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... }
閱讀 Truth Equality and JavaScript 了解更多
[?]
塊給所有多行的塊使用大括號
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }
**[[?]](#TOC)**注釋
使用 /** ... */ 進行多行注釋,包括描述,指定類型以及參數(shù)值和返回值
// bad // make() returns a new element // based on the passed in tag name // // @paramtag // @return element function make(tag) { // ...stuff... return element; } // good /** * make() returns a new element * based on the passed in tag name * * @param tag * @return element */ function make(tag) { // ...stuff... return element; }
使用 // 進行單行注釋,在評論對象的上面進行單行注釋,注釋前放一個空行.
// bad var active = true; // is current tab // good // is current tab var active = true; // bad function getType() { console.log("fetching type..."); // set the default type to "no type" var type = this._type || "no type"; return type; } // good function getType() { console.log("fetching type..."); // set the default type to "no type" var type = this._type || "no type"; return type; }
如果你有一個問題需要重新來看一下或如果你建議一個需要被實現(xiàn)的解決方法的話需要在你的注釋前面加上 FIXME 或 TODO 幫助其他人迅速理解
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; }
**[[?]](#TOC)**空白
將tab設為4個空格
// bad function() { ??var name; } // bad function() { ?var name; } // good function() { ????var name; }
大括號前放一個空格
// bad function test(){ console.log("test"); } // good function test() { console.log("test"); } // bad dog.set("attr",{ age: "1 year", breed: "Bernese Mountain Dog" }); // good dog.set("attr", { age: "1 year", breed: "Bernese Mountain Dog" });
在做長方法鏈時使用縮進.
// bad $("#items").find(".selected").highlight().end().find(".open").updateCount(); // good $("#items") .find(".selected") .highlight() .end() .find(".open") .updateCount(); // bad var 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); // good var 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);
**[[?]](#TOC)**逗號
不要將逗號放前面
// bad var once , upon , aTime; // good var once, upon, aTime; // bad var hero = { firstName: "Bob" , lastName: "Parr" , heroName: "Mr. Incredible" , superPower: "strength" }; // good var hero = { firstName: "Bob", lastName: "Parr", heroName: "Mr. Incredible", superPower: "strength" };
不要加多余的逗號,這可能會在IE下引起錯誤,同時如果多一個逗號某些ES3的實現(xiàn)會計算多數(shù)組的長度。
// bad var hero = { firstName: "Kevin", lastName: "Flynn", }; var heroes = [ "Batman", "Superman", ]; // good var hero = { firstName: "Kevin", lastName: "Flynn" }; var heroes = [ "Batman", "Superman" ];
**[[?]](#TOC)**分號
語句結束一定要加分號
// bad (function() { var name = "Skywalker" return name })() // good (function() { var name = "Skywalker"; return name; })(); // good ;(function() { var name = "Skywalker"; return name; })();
**[[?]](#TOC)**類型轉換
在語句的開始執(zhí)行類型轉換.
字符串:
// => this.reviewScore = 9; // bad var totalScore = this.reviewScore + ""; // good var totalScore = "" + this.reviewScore; // bad var totalScore = "" + this.reviewScore + " total score"; // good var totalScore = this.reviewScore + " total score";
對數(shù)字使用 parseInt 并且總是帶上類型轉換的基數(shù).
var inputValue = "4"; // bad var val = new Number(inputValue); // bad var val = +inputValue; // bad var val = inputValue >> 0; // bad var val = parseInt(inputValue); // good var val = Number(inputValue); // good var 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;
布爾值:
var age = 0; // bad var hasAge = new Boolean(age); // good var hasAge = Boolean(age); // good var hasAge = !!age;
**[[?]](#TOC)**命名約定
避免單個字符名,讓你的變量名有描述意義。
// bad function q() { // ...stuff... } // good function query() { // ..stuff.. }
當命名對象、函數(shù)和實例時使用駝峰命名規(guī)則
// bad var OBJEcttsssss = {}; var this_is_my_object = {}; var this-is-my-object = {}; function c() {}; var u = new user({ name: "Bob Parr" }); // good var thisIsMyObject = {}; function thisIsMyFunction() {}; var user = new User({ name: "Bob Parr" });
當命名構造函數(shù)或類時使用駝峰式大寫
// bad function user(options) { this.name = options.name; } var bad = new user({ name: "nope" }); // good function User(options) { this.name = options.name; } var good = new User({ name: "yup" });
命名私有屬性時前面加個下劃線 _
// bad this.__firstName__ = "Panda"; this.firstName_ = "Panda"; // good this._firstName = "Panda";
當保存對 this 的引用時使用 _this.
// bad function() { var self = this; return function() { console.log(self); }; } // bad function() { var that = this; return function() { console.log(that); }; } // good function() { var _this = this; return function() { console.log(_this); }; }
**[[?]](#TOC)**存取器
屬性的存取器函數(shù)不是必需的
如果你確實有存取器函數(shù)的話使用getVal() 和 setVal("hello")
// bad dragon.age(); // good dragon.getAge(); // bad dragon.age(25); // good dragon.setAge(25);
如果屬性是布爾值,使用isVal() 或 hasVal()
// bad if (!dragon.age()) { return false; } // good if (!dragon.hasAge()) { return false; }
可以創(chuàng)建get()和set()函數(shù),但是要保持一致
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]; };
**[[?]](#TOC)**構造器
給對象原型分配方法,而不是用一個新的對象覆蓋原型,覆蓋原型會使繼承出現(xiàn)問題。
function Jedi() { console.log("new jedi"); } // bad Jedi.prototype = { fight: function fight() { console.log("fighting"); }, block: function block() { console.log("blocking"); } }; // good Jedi.prototype.fight = function fight() { console.log("fighting"); }; Jedi.prototype.block = function block() { console.log("blocking"); };
方法可以返回 this 幫助方法可鏈。
// bad Jedi.prototype.jump = function() { this.jumping = true; return true; }; Jedi.prototype.setHeight = function(height) { this.height = height; }; var luke = new Jedi(); luke.jump(); // => true luke.setHeight(20) // => undefined // good Jedi.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);
可以寫一個自定義的toString()方法,但是確保它工作正常并且不會有副作用。
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(); };
**[[?]](#TOC)**事件
當給事件附加數(shù)據(jù)時,傳入一個哈希而不是原始值,這可以讓后面的貢獻者加入更多數(shù)據(jù)到事件數(shù)據(jù)里而不用找出并更新那個事件的事件處理器
// bad $(this).trigger("listingUpdated", listing.id); ... $(this).on("listingUpdated", function(e, listingId) { // do something with listingId });
更好:
// good $(this).trigger("listingUpdated", { listingId : listing.id }); ... $(this).on("listingUpdated", function(e, data) { // do something with data.listingId });
[?]
模塊模塊應該以 ! 開始,這保證了如果一個有問題的模塊忘記包含最后的分號在合并后不會出現(xiàn)錯誤
這個文件應該以駝峰命名,并在同名文件夾下,同時導出的時候名字一致
加入一個名為noConflict()的方法來設置導出的模塊為之前的版本并返回它
總是在模塊頂部聲明 "use strict";
// 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);
**[[?]](#TOC)**jQuery
緩存jQuery查詢
// bad function setSidebar() { $(".sidebar").hide(); // ...stuff... $(".sidebar").css({ "background-color": "pink" }); } // good function setSidebar() { var $sidebar = $(".sidebar"); $sidebar.hide(); // ...stuff... $sidebar.css({ "background-color": "pink" }); }
對DOM查詢使用級聯(lián)的 $(".sidebar ul") 或 $(".sidebar ul"),jsPerf
對有作用域的jQuery對象查詢使用 find
// 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");
**[[?]](#TOC)**許可
(The MIT License)
Copyright (c) 2012 Airbnb
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[?]
};文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/85914.html
摘要:點擊查看原文總結一下變量名函數(shù)名用駝峰,以小寫字母開頭逗號和操作符之后要有空格縮進為個空格其實現(xiàn)在有很多是個的語句的結尾有分號復合語句左花括號在首行末尾,且之前有空格右花括號另起一行,之前沒有空格結尾沒有括號對象左花括號不換行,之前有空格 點擊查看原文 總結一下: 變量名函數(shù)名用駝峰,以小寫字母開頭 逗號和操作符之后要有空格 縮進為4個空格(其實現(xiàn)在有很多是2個的 nodejs ...
摘要:創(chuàng)建可維護的設計規(guī)范為什么需要相信團隊工作中,不管是前端還是設計師都有被視覺統(tǒng)一問題折磨過的美好經(jīng)歷。所以在這,我先略過視覺稿,直接來說如何創(chuàng)建一分靈活可維護的設計規(guī)范。 創(chuàng)建可維護的設計規(guī)范(Living Style Guide) 為什么需要 Style Guide 相信團隊工作中,不管是前端還是設計師都有被 視覺統(tǒng)一問題 折磨過的美 (dan) 好 (teng) 經(jīng)歷。特別是在中大...
摘要:前端規(guī)范在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
摘要:前端規(guī)范在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
摘要:前端規(guī)范在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實際開發(fā)中,由于團隊成員編碼習慣不一,技術層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
閱讀 1127·2021-10-09 09:43
閱讀 18610·2021-09-22 15:52
閱讀 1071·2019-08-30 15:44
閱讀 3064·2019-08-30 15:44
閱讀 3253·2019-08-26 14:07
閱讀 914·2019-08-26 13:55
閱讀 2576·2019-08-26 13:41
閱讀 3095·2019-08-26 13:29