摘要:在中已經澄清分號恩,這也是規范一部分閱讀更多類型分配強制轉換執行強制類型轉換的語句。對于整型值大于位的進行位運算將導致不可預見的行為。在范圍內使用進行對象查詢譯文出處
類型 基本類型:訪問基本類型時,應該直接操作類型值
string
number
boolean
null
undefined
javascriptvar foo = 1; var bar = foo; bar = 9; console.log(foo, bar); // => 1, 9復合類型:訪問復合類型時,應該操作其引用
object
array
function
var foo = [1, 2]; var bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9對象
使用字面量語法創建對象
// bad var item = new Object(); // good var item = {};
不要使用保留字,在IE8中不起作用,更多相關信息
// bad var superman = { default: { clark: "kent" }, private: true }; // good var superman = { defaults: { clark: "kent" }, hidden: true };
使用易讀的同義詞代替保留字
// bad var superman = { class: "alien" }; // bad var superman = { klass: "alien" }; // good var superman = { type: "alien" };數組
使用字面量語法創建數組
// bad var items = new Array(); // good var items = [];
添加數組元素時,使用push而不是直接添加
var someStack = []; // bad someStack[someStack.length] = "abracadabra"; // good someStack.push("abracadabra");
需要復制數組時,可以使用slice,jsPerf的相關文章
var len = items.length; var itemsCopy = []; var i; // bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good itemsCopy = items.slice();
使用slice將類數組對象轉為數組
function trigger() { var args = Array.prototype.slice.call(arguments); ... }字符串
對字符串使用單引號
// 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.";
以編程方式創建字符串的時應該使用Array的join方法而不是通過連接符,尤其是在IE中:jsPerf.
var items; var messages; var length; var 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 = "
函數表達式
// anonymous function expression var anonymous = function() { return true; }; // named function expression var named = function named() { return true; }; // immediately-invoked function expression (IIFE) (function() { console.log("Welcome to the Internet. Please follow me."); })();
不要在非函數塊中(if, while, etc)聲明函數,盡管瀏覽器允許你分配函數給一個變量,但壞消息是,不同的瀏覽器用不同的方式解析它
注意:ECMA-262把塊定義為一組語句,但函數聲明不是一個語句:Read ECMA-262’s note
on this issue.
// bad if (currentUser) { function test() { console.log("Nope."); } } // good var test; if (currentUser) { test = function test() { console.log("Yup."); }; }
不要命名一個參數為arguments,否則它將優先于傳遞給每個函數作用域中的arguments對象,
// bad function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }屬性
使用點表示法訪問屬性
var luke = { jedi: true, age: 28 }; // bad var isJedi = luke["jedi"]; // good var isJedi = luke.jedi;
用變量訪問屬性時要使用下標表示法([])
var luke = { jedi: true, age: 28 }; function getProp(prop) { return luke[prop]; } var isJedi = getProp("jedi");變量
總是使用var聲明變量,不然其將變為全局變量。我們要想辦法避免全局空間污染
// bad superPower = new SuperPower(); // good var superPower = new SuperPower();
使用var聲明每個變量,這樣很容易添加新的變量聲明,而不用去擔心用a;替換a,
// bad var items = getItems(), goSportsTeam = true, dragonball = "z"; // bad // (compare to above, and try to spot the mistake) var items = getItems(), goSportsTeam = true; dragonball = "z"; // good var items = getItems(); var goSportsTeam = true; var dragonball = "z";
最后聲明未賦值的變量,這對于你需要根據之前已經賦值的變量對一個變量進行賦值時是很有幫助的
// bad var i, len, dragonball, items = getItems(), goSportsTeam = true; // bad var i; var items = getItems(); var dragonball; var goSportsTeam = true; var len; // good var items = getItems(); var goSportsTeam = true; var dragonball; var length; var 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; }聲明提升
變量聲明是在作用域的頂端,但是賦值沒有
// we know this wouldn"t work (assuming there // is no notDefined global variable) function example() { console.log(notDefined); // => throws a ReferenceError } // creating a variable declaration after you // reference the variable will work due to // variable hoisting. Note: the assignment // value of `true` is not hoisted. function example() { console.log(declaredButNotAssigned); // => undefined var declaredButNotAssigned = true; } // The interpreter is hoisting the variable // declaration to the top of the scope, // which means our example could be rewritten as: function example() { var declaredButNotAssigned; console.log(declaredButNotAssigned); // => undefined declaredButNotAssigned = true; }
匿名表達式能提升他們的變量名,但不能提升函數賦值
function example() { console.log(anonymous); // => undefined anonymous(); // => TypeError anonymous is not a function var anonymous = function() { console.log("anonymous function expression"); }; }
命名函數表達式會提升變量名,而不是函數名或者函數體
function example() { console.log(named); // => undefined named(); // => TypeError named is not a function superPower(); // => ReferenceError superPower is not defined var named = function superPower() { console.log("Flying"); }; } // the same is true when the function name // is the same as the variable name. function example() { console.log(named); // => undefined named(); // => TypeError named is not a function var named = function named() { console.log("named"); } }
函數聲明會提升變量名和函數體
function example() { superPower(); // => Flying function superPower() { console.log("Flying"); } }
更多信息指引:JavaScript Scoping & Hoisting by Ben Cherry.
比較運算符&相等使用===和!==代替==和!=
比較運算符進行計算時會利用ToBoolean方法進行強制轉換數據類型,并遵從一下規則
>Objects的計算值是true
>Undefined的計算值是false
>Boolean的計算值是boolean的值
>Numbers如果是-0,+0或者NaN,則計算值是false,反之是true
>Strings如果是空,則計算值是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... }語句塊
對多行的語句塊使用大括號
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }
對于使用if和else的多行語句塊,把else和if語句塊的右大括號放在同一行
// bad if (test) { thing1(); thing2(); } else { thing3(); } // good if (test) { thing1(); thing2(); } else { thing3(); }注釋
多行注釋使用/** … */,需包含一個描述、所有參數的具體類型和值以及返回值
// bad // make() returns a new element // based on the passed in tag name // // @param {String} tag // @return {Element} element function 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; }
單行注釋使用//,把單行注釋放在語句的上一行,并且在注釋之前空一行
// 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; }
如果你指出的問題需要重新定位或者提出一個待解決的問題需要實現,給注釋添加FIXME or TODO 前綴有利于其他開發者快速理解。這些注釋不同于通常的注釋,因為它們是可實施的。這些實施措施就是FIXME -- need to figure this out or TODO -- need to implement.
使用// FIXME:給一個問題作注釋
function Calculator() { // FIXME: shouldn"t use a global here total = 0; return this; }
使用//TODO:給問題解決方案作注釋
function Calculator() { // TODO: total should be configurable by an options param this.total = 0; return this; }空白
使用軟制表符設置兩個空格
// 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" });
在控制語句中(if, while etc),左括號之前留一個空格。函數的參數列表之前不要有空格
// bad if(isJedi) { fight (); } // good if (isJedi) { fight(); } // bad function fight () { console.log ("Swooosh!"); } // good function fight() { console.log("Swooosh!"); }
用空白分隔運算符
// bad var x=y+5; // good var x = y + 5;
用一個換行符結束文件
// bad (function(global) { // ...stuff... })(this); // bad (function(global) { // ...stuff... })(this);? ? // good (function(global) { // ...stuff... })(this);?
當調用很長的方法鏈時使用縮進,可以強調這行是方法調用,不是新的語句
// bad $("#items").find(".selected").highlight().end().find(".open").updateCount(); // 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").classed("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") .classed("led", true) .attr("width", (radius + margin) * 2) .append("svg:g") .attr("transform", "translate(" + (radius + margin) + "," + (radius + margin) + ")") .call(tron.led);
在語句塊和下一個語句之前留一個空行
// bad if (foo) { return bar; } return baz; // good if (foo) { return bar; } return baz; // bad var obj = { foo: function() { }, bar: function() { } }; return obj; // good var obj = { foo: function() { }, bar: function() { } }; return obj;逗號
不要在語句前留逗號
// bad var story = [ once , upon , aTime ]; // good var story = [ 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" };
不要有多余逗號:這會在IE6、IE7和IE9的怪異模式中導致一些問題;同時,在ES3的一些實現中,多余的逗號會增加數組的長度。在ES5中已經澄清(source)
// bad var hero = { firstName: "Kevin", lastName: "Flynn", }; var heroes = [ "Batman", "Superman", ]; // good var hero = { firstName: "Kevin", lastName: "Flynn" }; var heroes = [ "Batman", "Superman" ];分號
恩,這也是規范一部分
// bad (function() { var name = "Skywalker" return name })() // good (function() { var name = "Skywalker"; return name; })(); // good (guards against the function becoming an argument when two files with IIFEs are concatenated) ;(function() { var name = "Skywalker"; return name; })();
閱讀更多
類型分配&強制轉換執行強制類型轉換的語句。
Strings: // => 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";
使用parseInt對Numbers進行轉換,并帶一個進制作為參數
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);
無論出于什么原因,或許你做了一些”粗野”的事;或許parseInt成了你的瓶頸;或許考慮到性能,需要使用位運算,都要用注釋說明你為什么這么做
// 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;
注意:當使用位運算時,Numbers被視為64位值,但是位運算總是返回32位整型(source)。對于整型值大于32位的進行位運算將導致不可預見的行為。Discussion.最大的有符號32位整數是2,147,483,647
2147483647 >> 0 //=> 2147483647 2147483648 >> 0 //=> -2147483648 2147483649 >> 0 //=> -2147483647 Booleans: var age = 0; // bad var hasAge = new Boolean(age); // good var hasAge = Boolean(age); // good var hasAge = !!age;命名規范
避免單字母名稱,讓名稱具有描述性
// bad function q() { // ...stuff... } // good function query() { // ..stuff.. } 當命名對象、函數和實例時使用駱駝拼寫法 // bad var OBJEcttsssss = {}; 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" });
當命名構造函數或類名時,使用駝峰式寫法
// 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); }; }
命名函數時,下面的方式有利于堆棧跟蹤
// bad var log = function(msg) { console.log(msg); }; // good var log = function log(msg) { console.log(msg); };
注意:IE8和怪異模式下命名函數表示,戳此:http://kangax.github.io/nfe/
如果文件作為一個類被導出,文件名應該和類名保持一致
// file contents class CheckBox { // ... } module.exports = CheckBox; // in some other file // bad var CheckBox = require("./checkBox"); // bad var CheckBox = require("./check_box"); // good var CheckBox = require("./CheckBox");存取器
對于屬性,訪問器函數不是必須的
如果定義了存取器函數,應參照getVal() 和 setVal(‘hello’)格式.
// bad dragon.age(); // good dragon.getAge(); // bad dragon.age(25); // good dragon.setAge(25);
如果屬性時boolean,格式應為isVal() or hasVal().
// bad if (!dragon.age()) { return false; } // good if (!dragon.hasAge()) { return false; }
創建get() and set()函數時不錯的想法,但是要保持一致
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]; };構造函數
在原型對象上定義方法,而不是用新對象重寫它。重寫使繼承變為不可能:重置原型將重寫整個基類
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(); };事件
當在事件對象上附加數據時(無論是DOM事件還是如Backbone一樣擁有的私有事件),應傳遞散列對象而不是原始值,這可以讓隨后的貢獻者給事件對象添加更多的數據,而不必去查找或者更新每一個事件處理程序。舉個粟子,不要用下面的方式:
// 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 });模塊
模塊應該以 ! 開始,這能確保當腳本連接時,如果畸形模塊忘記導入,包括最后一個分號,不會產生錯誤。Explanation
文件應該以駝峰式命名,放在同名的文件夾中,和單出口的名稱相匹配
定義一個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);jQuery
jQuery對象變量使用前綴$
// bad var sidebar = $(".sidebar"); // good var $sidebar = $(".sidebar"); 緩存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" }); }
使用級聯$(‘.sidebar ul’)或父子$(‘.sidebar > ul’)選擇器進行DOM查詢。jsPerf
在范圍內使用find進行jQuery對象查詢
// bad $("ul", ".sidebar").hide(); // bad $(".sidebar").find("ul").hide(); // good $(".sidebar ul").hide(); // good $(".sidebar > ul").hide(); // good $sidebar.find("ul").hide();
譯文出處:http://www.ido321.com/1520.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85636.html
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內容皆在微信公眾號,歡迎關注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。原理微信熱更新方案漲知識了,熱更新是以后的標配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內容皆在微信公眾號,歡迎關注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動力。 遠上寒山石徑...
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內容皆在微信公眾號,歡迎關注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。原理微信熱更新方案漲知識了,熱更新是以后的標配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內容皆在微信公眾號,歡迎關注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動力。 遠上寒山石徑...
摘要:因為用戶不用在第一次進入應用時下載所有代碼,用戶能更快的看到頁面并與之交互。譯高階函數利用和來編寫更易維護的代碼高階函數可以幫助你增強你的,讓你的代碼更具有聲明性。知道什么時候和怎樣使用高階函數是至關重要的。 Vue 折騰記 - (10) 給axios做個挺靠譜的封裝(報錯,鑒權,跳轉,攔截,提示) 稍微改改都能直接拿來用~~~喲吼吼,喲吼吼..... 如何無痛降低 if else 面...
摘要:整理收藏一些優秀的文章及大佬博客留著慢慢學習原文協作規范中文技術文檔協作規范阮一峰編程風格凹凸實驗室前端代碼規范風格指南這一次,徹底弄懂執行機制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環有何區別筆試題事件循環機制異步編程理解的異步 better-learning 整理收藏一些優秀的文章及大佬博客留著慢慢學習 原文:https://www.ahwgs.cn/youxiuwenzhan...
摘要:通用格式規范縮進一次縮進個空格,不要使用或者混合和空格的縮進。語義化根據使用場景選擇正確的元素有時被錯誤的稱為標簽。格式規范引號屬性值用雙引號。風格規范和命名使用有含義的和名稱。和單位值為時不用添加單位。 原文 Google HTML/CSS Style Guide 背景 這篇文章定義了 HTML 和 CSS 的格式和代碼規范,旨在提高代碼質量和協作效率。 通用樣式規范 協議 圖片,樣...
閱讀 2835·2023-04-25 17:59
閱讀 676·2023-04-25 15:05
閱讀 669·2021-11-25 09:43
閱讀 3026·2021-10-12 10:13
閱讀 3532·2021-09-27 13:59
閱讀 3577·2021-09-23 11:21
閱讀 3872·2021-09-08 09:35
閱讀 561·2019-08-29 17:12