摘要:在作用域頂部聲明變量,避免變量聲明和賦值引起的相關(guān)問題。分號(hào)語(yǔ)句結(jié)束一定要加分號(hào)類型轉(zhuǎn)換在語(yǔ)句的開始執(zhí)行類型轉(zhuǎn)換字符串對(duì)數(shù)字使用并且總是帶上類型轉(zhuǎn)換的基數(shù)布爾值命名約定避免單個(gè)字符名,讓你的變量名有描述意義。
JavaScript規(guī)范 內(nèi)容列表原文:https://github.com/airbnb/javascript
類型
對(duì)象
數(shù)組
字符串
函數(shù)
屬性
變量
條件表達(dá)式和等號(hào)
塊
注釋
空白
逗號(hào)
分號(hào)
類型轉(zhuǎn)換
命名約定
存取器
構(gòu)造器
事件
模塊
jQuery
ES5 兼容性
性能
資源
哪些人在使用
翻譯
JavaScript風(fēng)格指南
貢獻(xiàn)者
許可
類型
原始值: 相當(dāng)于傳值
string
number
boolean
null
undefined
var foo = 1, bar = foo; bar = 9; console.log(foo, bar); // => 1, 9
復(fù)雜類型: 相當(dāng)于傳引用
object
array
function
var foo = [1, 2], bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9
**[[?]](#TOC)**對(duì)象
使用字面值創(chuàng)建對(duì)象
// 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ù)組的長(zhǎng)度,使用push
var someStack = []; // bad someStack[someStack.length] = "abracadabra"; // good someStack.push("abracadabra");
當(dāng)你需要拷貝數(shù)組時(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ù)組的對(duì)象轉(zhuǎn)成數(shù)組.
function trigger() { var args = Array.prototype.slice.call(arguments); ... }
**[[?]](#TOC)**字符串
對(duì)字符串使用單引號(hào) ""
// bad var name = "Bob Parr"; // good var name = "Bob Parr"; // bad var fullName = "Bob " + this.lastName; // good var fullName = "Bob " + this.lastName;
超過(guò)80個(gè)字符的字符串應(yīng)該使用字符串連接換行
注: 如果過(guò)度使用,長(zhǎng)字符串連接可能會(huì)對(duì)性能有影響. 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.";
編程時(shí)使用join而不是字符串連接來(lái)構(gòu)建字符串,特別是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ù)表達(dá)式:
// 匿名函數(shù)表達(dá)式 var anonymous = function() { return true; }; // 有名函數(shù)表達(dá)式 var named = function named() { return true; }; // 立即調(diào)用函數(shù)表達(dá)式 (function() { console.log("Welcome to the Internet. Please follow me."); })();
絕對(duì)不要在一個(gè)非函數(shù)塊里聲明一個(gè)函數(shù),把那個(gè)函數(shù)賦給一個(gè)變量。瀏覽器允許你這么做,但是它們解析不同。
注: ECMA-262定義把塊定義為一組語(yǔ)句,函數(shù)聲明不是一個(gè)語(yǔ)句。閱讀ECMA-262對(duì)這個(gè)問題的說(shuō)明.
// bad if (currentUser) { function test() { console.log("Nope."); } } // good if (currentUser) { var test = function test() { console.log("Yup."); }; }
絕對(duì)不要把參數(shù)命名為 arguments, 這將會(huì)逾越函數(shù)作用域內(nèi)傳過(guò)來(lái)的 arguments 對(duì)象.
// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }
**[[?]](#TOC)**屬性
當(dāng)使用變量訪問屬性時(shí)使用中括號(hào).
var luke = { jedi: true, age: 28 }; function getProp(prop) { return luke[prop]; } var isJedi = getProp("jedi");
**[[?]](#TOC)**變量
總是使用 var 來(lái)聲明變量,如果不這么做將導(dǎo)致產(chǎn)生全局變量,我們要避免污染全局命名空間。
// bad superPower = new SuperPower(); // good var superPower = new SuperPower();
使用一個(gè) var 以及新行聲明多個(gè)變量,縮進(jìn)4個(gè)空格。
// bad var items = getItems(); var goSportsTeam = true; var dragonball = "z"; // good var items = getItems(), goSportsTeam = true, dragonball = "z";
最后再聲明未賦值的變量,當(dāng)你想引用之前已賦值變量的時(shí)候很有用。
// 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;
在作用域頂部聲明變量,避免變量聲明和賦值引起的相關(guān)問題。
// 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)**條件表達(dá)式和等號(hào)
適當(dāng)使用 === 和 !== 以及 == 和 !=.
條件表達(dá)式的強(qiáng)制類型轉(zhuǎn)換遵循以下規(guī)則:
對(duì)象 被計(jì)算為 true
Undefined 被計(jì)算為 false
Null 被計(jì)算為 false
布爾值 被計(jì)算為 布爾的值
數(shù)字 如果是 +0, -0, or NaN 被計(jì)算為 false , 否則為 true
字符串 如果是空字符串 "" 則被計(jì)算為 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 了解更多
[?]
塊給所有多行的塊使用大括號(hào)
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }
**[[?]](#TOC)**注釋
使用 /** ... */ 進(jìn)行多行注釋,包括描述,指定類型以及參數(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; }
使用 // 進(jìn)行單行注釋,在評(píng)論對(duì)象的上面進(jìn)行單行注釋,注釋前放一個(gè)空行.
// 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; }
如果你有一個(gè)問題需要重新來(lái)看一下或如果你建議一個(gè)需要被實(shí)現(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設(shè)為4個(gè)空格
// bad function() { ??var name; } // bad function() { ?var name; } // good function() { ????var name; }
大括號(hào)前放一個(gè)空格
// 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" });
在做長(zhǎng)方法鏈時(shí)使用縮進(jìn).
// 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)**逗號(hào)
不要將逗號(hào)放前面
// 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" };
不要加多余的逗號(hào),這可能會(huì)在IE下引起錯(cuò)誤,同時(shí)如果多一個(gè)逗號(hào)某些ES3的實(shí)現(xiàn)會(huì)計(jì)算多數(shù)組的長(zhǎng)度。
// bad var hero = { firstName: "Kevin", lastName: "Flynn", }; var heroes = [ "Batman", "Superman", ]; // good var hero = { firstName: "Kevin", lastName: "Flynn" }; var heroes = [ "Batman", "Superman" ];
**[[?]](#TOC)**分號(hào)
語(yǔ)句結(jié)束一定要加分號(hào)
// bad (function() { var name = "Skywalker" return name })() // good (function() { var name = "Skywalker"; return name; })(); // good ;(function() { var name = "Skywalker"; return name; })();
**[[?]](#TOC)**類型轉(zhuǎn)換
在語(yǔ)句的開始執(zhí)行類型轉(zhuǎn)換.
字符串:
// => 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";
對(duì)數(shù)字使用 parseInt 并且總是帶上類型轉(zhuǎn)換的基數(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)**命名約定
避免單個(gè)字符名,讓你的變量名有描述意義。
// bad function q() { // ...stuff... } // good function query() { // ..stuff.. }
當(dāng)命名對(duì)象、函數(shù)和實(shí)例時(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" });
當(dāng)命名構(gòu)造函數(shù)或類時(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" });
命名私有屬性時(shí)前面加個(gè)下劃線 _
// bad this.__firstName__ = "Panda"; this.firstName_ = "Panda"; // good this._firstName = "Panda";
當(dāng)保存對(duì) this 的引用時(shí)使用 _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í)有存取器函數(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)**構(gòu)造器
給對(duì)象原型分配方法,而不是用一個(gè)新的對(duì)象覆蓋原型,覆蓋原型會(huì)使繼承出現(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);
可以寫一個(gè)自定義的toString()方法,但是確保它工作正常并且不會(huì)有副作用。
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)**事件
當(dāng)給事件附加數(shù)據(jù)時(shí),傳入一個(gè)哈希而不是原始值,這可以讓后面的貢獻(xiàn)者加入更多數(shù)據(jù)到事件數(shù)據(jù)里而不用找出并更新那個(gè)事件的事件處理器
// 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 });
[?]
模塊模塊應(yīng)該以 ! 開始,這保證了如果一個(gè)有問題的模塊忘記包含最后的分號(hào)在合并后不會(huì)出現(xiàn)錯(cuò)誤
這個(gè)文件應(yīng)該以駝峰命名,并在同名文件夾下,同時(shí)導(dǎo)出的時(shí)候名字一致
加入一個(gè)名為noConflict()的方法來(lái)設(shè)置導(dǎo)出的模塊為之前的版本并返回它
總是在模塊頂部聲明 "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" }); }
對(duì)DOM查詢使用級(jí)聯(lián)的 $(".sidebar ul") 或 $(".sidebar ul"),jsPerf
對(duì)有作用域的jQuery對(duì)象查詢使用 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.
[?]
};文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85914.html
摘要:點(diǎn)擊查看原文總結(jié)一下變量名函數(shù)名用駝峰,以小寫字母開頭逗號(hào)和操作符之后要有空格縮進(jìn)為個(gè)空格其實(shí)現(xiàn)在有很多是個(gè)的語(yǔ)句的結(jié)尾有分號(hào)復(fù)合語(yǔ)句左花括號(hào)在首行末尾,且之前有空格右花括號(hào)另起一行,之前沒有空格結(jié)尾沒有括號(hào)對(duì)象左花括號(hào)不換行,之前有空格 點(diǎn)擊查看原文 總結(jié)一下: 變量名函數(shù)名用駝峰,以小寫字母開頭 逗號(hào)和操作符之后要有空格 縮進(jìn)為4個(gè)空格(其實(shí)現(xiàn)在有很多是2個(gè)的 nodejs ...
摘要:創(chuàng)建可維護(hù)的設(shè)計(jì)規(guī)范為什么需要相信團(tuán)隊(duì)工作中,不管是前端還是設(shè)計(jì)師都有被視覺統(tǒng)一問題折磨過(guò)的美好經(jīng)歷。所以在這,我先略過(guò)視覺稿,直接來(lái)說(shuō)如何創(chuàng)建一分靈活可維護(hù)的設(shè)計(jì)規(guī)范。 創(chuàng)建可維護(hù)的設(shè)計(jì)規(guī)范(Living Style Guide) 為什么需要 Style Guide 相信團(tuán)隊(duì)工作中,不管是前端還是設(shè)計(jì)師都有被 視覺統(tǒng)一問題 折磨過(guò)的美 (dan) 好 (teng) 經(jīng)歷。特別是在中大...
摘要:前端規(guī)范在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個(gè)名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
摘要:前端規(guī)范在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個(gè)名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
摘要:前端規(guī)范在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。是定義了一種的命名規(guī)范,每個(gè)名稱及其組成部分都是存在一定的含義。 前端規(guī)范 在實(shí)際開發(fā)中,由于團(tuán)隊(duì)成員編碼習(xí)慣不一,技術(shù)層次不同,開發(fā)前定制并遵循一種代碼規(guī)范能提高代碼質(zhì)量,增加開發(fā)效率。 Javascript Javascript規(guī)范直接參考airbnb: ES6 ...
閱讀 1124·2021-10-09 09:43
閱讀 18551·2021-09-22 15:52
閱讀 1063·2019-08-30 15:44
閱讀 3056·2019-08-30 15:44
閱讀 3248·2019-08-26 14:07
閱讀 910·2019-08-26 13:55
閱讀 2570·2019-08-26 13:41
閱讀 3092·2019-08-26 13:29