【转】JavaScript 风格指南/编码规范(Airbnb公司版)
原文转自:http://blog.jobbole.com/79484/
Airbnb 是一家位于美国旧金山的公司,本文是其内部的 JavaScript 风格指南/编码规范,在 Github 上有 11,000+ Star,2100+ fork,前端开发者可参考。
- 基本类型:当你访问基本类型时,你是直接对它的值进行操作。
stringnumberbooleannullundefined123456varfoo =1,bar = foo;bar =9;console.log(foo, bar);// => 1, 9
objectarrayfunction
|
1
2
3
4
5
6
|
var foo = [1, 2],bar = foo;bar[0] = 9;console.log(foo[0], bar[0]); // => 9, 9 |
对象
- 使用字面量语法来创建对象
- 12345
// badvaritem =newObject();// goodvaritem = {};
- 不要使用保留字作为“键值”,因为在IE8不能运行。More info
- 1234567891011
// badvarsuperman = {default: { clark:'kent'},private:true};// goodvarsuperman = {defaults: { clark:'kent'},hidden:true}; - 使用容易理解的同义词来替代保留字
- 1234567891011121314
// badvarsuperman = {class:'alien'};// badvarsuperman = {klass:'alien'};// goodvarsuperman = {type:'alien'}; 数组
- 使用字面量语法来创建数组
- 12345
// badvaritems =newArray();// goodvaritems = []; - 如果你不知道数组长度,数组添加成员使用push方法。
- 1234567
varsomeStack = [];// badsomeStack[someStack.length] ='abracadabra';// goodsomeStack.push('abracadabra'); - 当你需要复制一个数组时,使用数组的slice方法。jsPerf
- 1234567891011
varlen = items.length,itemsCopy = [],i;// badfor(i =0; i < len; i++) {itemsCopy[i] = items[i];}// gooditemsCopy = items.slice(); - 当你需要把“类似数组对象”转为数组时,使用数组的slice方法。
- 1234
functiontrigger() {varargs =Array.prototype.slice.call(arguments);...} 字符串
- 字符串使用单引号‘’
- 1234567891011
// badvarname ="Bob Parr";// goodvarname ='Bob Parr';// badvarfullName ="Bob "+this.lastName;// goodvarfullName ='Bob '+this.lastName; - 大于80个元素的字符串需要通过分隔符进行多行操作。
- 注意:如果在长字符串中过度使用分隔符会影响性能。. jsPerf & Discussion
- 12345678910111213
// badvarerrorMessage ='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.';// badvarerrorMessage = 'Thisisasuperlong error that was thrown becauseof Batman. When you stop to think about how Batman had anything todowiththis, you wouldgetnowherefast.';// goodvarerrorMessage ='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.
- 1234567891011121314151617181920212223242526272829303132333435363738
varitems,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;// badfunctioninbox(messages) {items ='<ul>';for(i =0; i < length; i++) {items +='<li>'+ messages[i].message +'</li>';}returnitems +'</ul>';}// goodfunctioninbox(messages) {items = [];for(i =0; i < length; i++) {items[i] = messages[i].message;}return'<ul><li>'+ items.join('</li><li>') +'</li></ul>'; 函数
- 函数表达式
- 1234567891011121314
// anonymous function expressionvaranonymous =function() {returntrue;};// named function expressionvarnamed =functionnamed() {returntrue;};// immediately-invoked function expression (IIFE)(function() {console.log('Welcome to the Internet. Please follow me.');})(); - 不要直接在非函数块(if,while等)里声明一个函数,最好将函数赋值给一个变量。虽然浏览器允许你在非函数块中声明函数,但是由于不同的浏览器对Javascript的解析方式不同,这样做就很可能造成麻烦。
- 注意:ECMA-262 将块定义为一组语句,而函数声明不是语句。Read ECMA-262′s note on this issue
- 1234567891011121314
// badif(currentUser) {functiontest() {console.log('Nope.');}}// goodvartest;if(currentUser) {test =functiontest() {console.log('Yup.');};} - 不要将参数命名为arguments,它将在每个函数的作用范围内优先于arguments对象。
- 123456789
// badfunctionnope(name, options, arguments) {// ...stuff...}// goodfunctionyup(name, options, args) {// ...stuff...} 属性
- 使用点符号 . 来访问属性
- 12345678910
varluke = {jedi:true,age:28};// badvarisJedi = luke['jedi'];// goodvarisJedi = luke.jedi; - 当你在变量中访问属性时,使用[ ]符号
- 12345678910
varluke = {jedi:true,age:28};functiongetProp(prop) {returnluke[prop];}varisJedi = getProp('jedi'); 变量
- 使用var来声明变量,否则将声明全局变量,我们需要尽量避免污染全局命名空间,Captain Planet这样警告过我们。
- 12345
// badsuperPower =newSuperPower();// goodvarsuperPower =newSuperPower(); - 多个变量时只使用一个var声明,每个变量占一新行。
- 123456789
// badvaritems = getItems();vargoSportsTeam =true;vardragonball ='z';// goodvaritems = getItems(),goSportsTeam =true,dragonball ='z'; - 最后再声明未赋值的变量,这对你之后需要依赖之前变量的变量赋值会有帮助。
- 123456789101112131415161718
// badvari, len, dragonball,items = getItems(),goSportsTeam =true;// badvari, items = getItems(),dragonball,goSportsTeam =true,len;// goodvaritems = getItems(),goSportsTeam =true,dragonball,length,i;· - 在范围内将变量赋值置顶,这有助于避免变量声明和赋值提升相关的问题
- 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
// badfunction() {test();console.log('doing stuff..');//..other stuff..varname = getName();if(name ==='test') {returnfalse;}returnname;}// goodfunction() {varname = getName();test();console.log('doing stuff..');//..other stuff..if(name ==='test') {returnfalse;}returnname;}// badfunction() {varname = getName();if(!arguments.length) {returnfalse;}returntrue;}// goodfunction() {if(!arguments.length) {returnfalse;}varname = getName();returntrue;} 提升
- 变量声明在范围内提升,但赋值并没有提升
- 1234567891011121314151617181920212223
// we know this wouldn't work (assuming there// is no notDefined global variable)functionexample() {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.functionexample() {console.log(declaredButNotAssigned);// => undefinedvardeclaredButNotAssigned =true;}// The interpreter is hoisting the variable// declaration to the top of the scope.// Which means our example could be rewritten as:functionexample() {vardeclaredButNotAssigned;console.log(declaredButNotAssigned);// => undefineddeclaredButNotAssigned =true;} - 匿名函数表达式提升变量名,但函数赋值并没有提升,
- 123456789
·functionexample() {console.log(anonymous);// => undefinedanonymous();// => TypeError anonymous is not a functionvaranonymous =function() {console.log('anonymous function expression');};} - 命名函数表达式提升变量名,但函数名字和函数体并没有提升。
- 1234567891011121314151617181920212223
functionexample() {console.log(named);// => undefinednamed();// => TypeError named is not a functionsuperPower();// => ReferenceError superPower is not definedvarnamed =functionsuperPower() {console.log('Flying');};}// the same is true when the function name// is the same as the variable name.functionexample() {console.log(named);// => undefinednamed();// => TypeError named is not a functionvarnamed =functionnamed() {console.log('named');}} - 函数声明能提升他们的函数名和函数体
- 1234567
functionexample() {superPower();// => FlyingfunctionsuperPower() {console.log('Flying');}} - 更多的信息在JavaScript Scoping & Hoisting by Ben Cherry
条件表达式和相等
- 条件表达式强制使用 ToBoolean方法进行解析,并遵从以下简单的规则Object :返回 true
- Undefined: 返回 false
- Null: 返回 false
- Booleans :返回 boolean的值
- Numbers :如果是+0, -0, or NaN返回 false, 其他则 true
- Strings :空字符串
''返回 false 其他返回true - 1234
if([0]) {// true// An array is an object, objects evaluate to true} - 使用简易方式
- 12345678910111213141516171819
// badif(name !=='') {// ...stuff...}// goodif(name) {// ...stuff...}// badif(collection.length >0) {// ...stuff...}// goodif(collection.length) {// ...stuff...} - 更多的信息查看 Truth Equality and JavaScript by Angus Croll
块
- 在多行块中使用大括号
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// badif (test) return false;// goodif (test) return false;// goodif (test) { return false;}// badfunction() { return false; }// goodfunction() { return false;} |
注释
- 多行注释使用
/** ... */,包括描述,指定类型、所有参数的值和返回值 - 123456789101112131415161718192021222324252627
// bad// make() returns a new element// based on the passed in tag name//// @param <String> tag// @return <Element> elementfunctionmake(tag) {// ...stuff...returnelement;}// good/*** make() returns a new element* based on the passed in tag name** @param <String> tag* @return <Element> element*/functionmake(tag) {// ...stuff...returnelement;}
- 单行注释使用 //, 在注释的内容前另起一行进行单行注释,并在注释前留一空行。
- 12345678910111213141516171819202122232425
// badvaractive =true;// is current tab// good// is current tabvaractive =true;// badfunctiongetType() {console.log('fetching type...');// set the default type to 'no type'vartype =this._type ||'no type';returntype;}// goodfunctiongetType() {console.log('fetching type...');// set the default type to 'no type'vartype =this._type ||'no type';returntype;} - 在你的注释加上FIXME或TODO的前缀可以帮助其他开发者迅速理解你指出的问题和需要的帮助,以及你建议需要完善的解决问题,这跟常规注释不一样因为其具有可行动性,FIXME——是需要解决的而TODO——是需要完善的
- 使用
// FIXME:来标记问题 - 1234567
functionCalculator() {// FIXME: shouldn't use a global heretotal =0;returnthis;} - 使用 // TODO:给待解决问题进行标注
- 1234567
functionCalculator() {// TODO: total should be configurable by an options paramthis.total =0;returnthis;} 空格
- 使用tabs设置两个空格
- 1234567891011121314
// badfunction() {∙∙∙∙varname;}// badfunction() {∙varname;}// goodfunction() {∙∙varname;} - 分支前面空一格
- 123456789101112131415161718192021
// badfunctiontest(){console.log('test');}// goodfunctiontest() {console.log('test');}// baddog.set('attr',{age:'1 year',breed:'Bernese Mountain Dog'});// gooddog.set('attr', {age:'1 year',breed:'Bernese Mountain Dog'}); - 操作符前后空一格
- 12345
// badvarx=y+5;// goodvarx = y +5; - 文件末尾用换行符结束
- 1234567891011121314
// bad(function(global) {// ...stuff...})(this);// bad(function(global) {// ...stuff...})(this);// good(function(global) {// ...stuff...})(this) - 使用长方法链时使用缩进
- 1234567891011121314151617181920212223242526
// bad$('#items').find('.selected').highlight().end().find('.open').updateCount();// good$('#items').find('.selected').highlight().end().find('.open').updateCount();// badvarleds = 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);// goodvarleds = 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); 逗号
- 不要在句首使用逗号
- 12345678910111213141516171819202122232425
// badvaronce, upon, aTime;// goodvaronce,upon,aTime;// badvarhero = {firstName:'Bob', lastName:'Parr', heroName:'Mr. Incredible', superPower:'strength'};// goodvarhero = {firstName:'Bob',lastName:'Parr',heroName:'Mr. Incredible',superPower:'strength'}; - 不要使用多余的逗号,这在IE6/7 和 IE9的混杂模式中会造成问题,同样,在ES3中有些实现,如果使用多余的逗号将增加数组的长度,这在ES5中有阐明(source):
- 123456789101112131415161718192021
// badvarhero = {firstName:'Kevin',lastName:'Flynn',};varheroes = ['Batman','Superman',];// goodvarhero = {firstName:'Kevin',lastName:'Flynn'};varheroes = ['Batman','Superman']; 分号
1234567891011121314151617// bad(function() {varname ='Skywalker'returnname})()// good(function() {varname ='Skywalker';returnname;})();// good (guards against the function becoming an argument when two files with IIFEs are concatenated);(function() {varname ='Skywalker';returnname;})();转型&强制
- 在语句的开头执行强制转型。
- Strings:
- 12345678910111213
// => this.reviewScore = 9;// badvartotalScore =this.reviewScore +'';// goodvartotalScore =''+this.reviewScore;// badvartotalScore =''+this.reviewScore +' total score';// goodvartotalScore =this.reviewScore +' total score'; - 使用
parseInt对Numbers型进行强制转型。 - 12345678910111213141516171819
varinputValue ='4';// badvarval =newNumber(inputValue);// badvarval = +inputValue;// badvarval = inputValue >>0;// badvarval =parseInt(inputValue);// goodvarval =Number(inputValue);// goodvarval =parseInt(inputValue,10); - 如果出于某种原因你需要做些特别的事,而
parseInt是你的瓶颈,出于性能考虑你需要使用位移,那么留下你的注释来解释原因。 - 1234567
// good/*** parseInt was the reason my code was slow.* Bitshifting the String to coerce it to a* Number made it a lot faster.*/varval = inputValue >>0; - 注意:小心位移操作符,Numbers代表着64位的值,而位移操作符只能返回32位的整型,位移对于大于32位的整型的值会有不好的影响,32位最大的有符号整型是2,147,483,647。
- (有关讨论:Discussion)
- 123
2147483647>>0//=> 21474836472147483648>>0//=> -21474836482147483649>>0//=> -2147483647 - Booleans:
- 12345678910
varage =0;// badvarhasAge =newBoolean(age);// goodvarhasAge =Boolean(age);// goodvarhasAge = !!age; 命名规则
- 不要使用一个字母命名,而应该用单词描述
- 123456789
// badfunctionq() {// ...stuff...}// goodfunctionquery() {// ..stuff..} - 使用驼峰法来给对象、函数、实例命名。
- 1234567891011121314
// badvarOBJEcttsssss = {};varthis_is_my_object = {};functionc() {}varu =newuser({name:'Bob Parr'});// goodvarthisIsMyObject = {};functionthisIsMyFunction() {}varuser =newUser({name:'Bob Parr'}); - 使用驼峰式大小写给构造函数和类命名。
- 1234567891011121314151617
// badfunctionuser(options) {this.name = options.name;}varbad =newuser({name:'nope'});// goodfunctionUser(options) {this.name = options.name;}vargood =newUser({name:'yup'}); - 使用下划线前缀_来命名私有属性。
- 123456
// badthis.__firstName__ ='Panda';this.firstName_ ='Panda';// goodthis._firstName ='Panda'; - 储存this的引用使用_this
- 1234567891011121314151617181920212223
// badfunction() {varself =this;returnfunction() {console.log(self);};}// badfunction() {varthat =this;returnfunction() {console.log(that);};}// goodfunction() {var_this =this;returnfunction() {console.log(_this);};} - 给你的函数命名,这有助于堆栈重写
- 123456789
// badvarlog =function(msg) {console.log(msg);};// goodvarlog =functionlog(msg) {console.log(msg);}; - 注意:IE8以下还有一些关于命名函数表达式的怪癖。详情见http://kangax.github.io/nfe/
访问器
- 如果你创建访问函数使用getVal() 和 setVal(‘hello’)
- 1234567891011
// baddragon.age();// gooddragon.getAge();// baddragon.age(25);// gooddragon.setAge(25);
如果这个属性是boolean,使用isVal() 或者 hasVal()
|
1
2
3
4
5
6
7
8
9
|
// badif (!dragon.age()) { return false;}// goodif (!dragon.hasAge()) { return false;} |
.也可以使用get() 和 set()函数来创建,但是必须一致。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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];}; |
构造器
- 给原型对象添加方法,相比用新对象重写原型,重写原型会有继承问题。如果你要重写原型方法,请重写基础方法。
- 1234567891011121314151617181920212223
functionJedi() {console.log('new jedi');}// badJedi.prototype = {fight:functionfight() {console.log('fighting');},block:functionblock() {console.log('blocking');}};// goodJedi.prototype.fight =functionfight() {console.log('fighting');};Jedi.prototype.block =functionblock() {console.log('blocking');}; - 方法返回this有助于方法链
- 1234567891011121314151617181920212223242526272829
// badJedi.prototype.jump =function() {this.jumping =true;returntrue;};Jedi.prototype.setHeight =function(height) {this.height = height;};varluke =newJedi();luke.jump();// => trueluke.setHeight(20);// => undefined// goodJedi.prototype.jump =function() {this.jumping =true;returnthis;};Jedi.prototype.setHeight =function(height) {this.height = height;returnthis;};varluke =newJedi();luke.jump().setHeight(20); - 可以重写常规的toString()方法。但必须保证可以成功运行并没有别的影响
- 123456789101112
functionJedi(options) {options || (options = {});this.name = options.name ||'no name';}Jedi.prototype.getName =functiongetName() {returnthis.name;};Jedi.prototype.toString =functiontoString() {return'Jedi - '+this.getName();}; - 将为事件加载数据时(不管是DOM事件还是其他专用事件的,比如Backbone事件)用散列表来取代原始值。因为这将允许后续添加更多的数据载入事件而不用更新每个事件的处理程序。例如:
|
1
2
3
4
5
6
7
8
|
// bad$(this).trigger('listingUpdated', listing.id);...$(this).on('listingUpdated', function(e, listingId) { // do something with listingId}); |
更好的方式:
|
1
2
3
4
5
6
7
8
|
// good$(this).trigger('listingUpdated', { listingId : listing.id });...$(this).on('listingUpdated', function(e, data) { // do something with data.listingId}); |
模块
- 模块应该以 “!”开始,以确保当模块忘记包含最后一个分号时,在脚本连接时不会报错。
- 文档需要用驼峰法命名,同一文件内要用一样的名字以及要与单个输出相匹配。
- 增加一个叫
noConflict()的方法,使模块输出早期版本并返回。 - 在模块开始的部位声明
'use strict'。 - 123456789101112131415161718
// fancyInput/fancyInput.js!function(global) {'use strict';varpreviousFancyInput = global.FancyInput;functionFancyInput(options) {this.options = options || {};}FancyInput.noConflict =functionnoConflict() {global.FancyInput = previousFancyInput;returnFancyInput;};global.FancyInput = FancyInput;}(this);
jQuery
- JQuery对象变量前缀使用$
- 12345
// badvarsidebar = $('.sidebar');// goodvar$sidebar = $('.sidebar'); - jQuery缓存查找
- 12345678910111213141516171819202122
// badfunctionsetSidebar() {$('.sidebar').hide();// ...stuff...$('.sidebar').css({'background-color':'pink'});}// goodfunctionsetSidebar() {var$sidebar = $('.sidebar');$sidebar.hide();// ...stuff...$sidebar.css({'background-color':'pink'});} - 在DOM查询中使用层叠样式
$('.sidebar ul')或parent > child$('.sidebar > ul'). jsPerf
- 使用find来查找jQuery对象
- 1234567891011121314
// bad$('ul','.sidebar').hide();// bad$('.sidebar').find('ul').hide();// good$('.sidebar ul').hide();// good$('.sidebar > ul').hide();// good$sidebar.find('ul').hide();
【转】JavaScript 风格指南/编码规范(Airbnb公司版)的更多相关文章
- 浅谈 JavaScript 编程语言的编码规范
对于熟悉 C/C++ 或 Java 语言的工程师来说,JavaScript 显得灵活,简单易懂,对代码的格式的要求也相对松散.很容易学习,并运用到自己的代码中.也正因为这样,JavaScript 的编 ...
- JavaScript最全编码规范
转载: JavaScript最全编码规范 类型 ●基本类型:访问基本类型时,应该直接操作类型值 ●string ●number ●boolean ●null ●undefined var foo = ...
- JavaScript 编码规范(中文/Airbnb公司版)
Airbnb 是一家位于美国旧金山的公司,本文是其内部的 JavaScript编码规范,写得比较全面,在 Github 上有 16,686 + Star,3,080 + fork,前端开发人员可参考. ...
- Google 开源项目风格指南阅读笔记(C++版)
虽说是编程风格指南,可是干货也不少,非常多C++的有用技术在里面. 头文件 通常每一个.cpp文件都相应一个.h文件:#define保护全部头文件都应该使用#define防止头文件被多重包括,为保证唯 ...
- JavaScript 风格指南
来源于: https://github.com/alivebao/clean-code-js 目录 介绍 变量 函数 对象和数据结构 类 测试 并发 错误处理 格式化 注释 介绍 作者根据 Rober ...
- 《编写可维护的JavaScript》——JavaScript编码规范(五)
语句和表达式 在JavaScript中,诸如if和for之类的语句有两种写法,使用花括号的多行代码或者不使用花括号的单行代码.比如: //不好的写法,尽管这是合法的JavaScript代码 if (c ...
- 《编写可维护的JavaScript》——JavaScript编码规范(三)
啦啦啦啦啦,今天第二篇随笔\(^o^)/~ ////////////////////////////////正文分割线////////////////////////////////////// 直接 ...
- [转]JavaScript程序编码规范
原文:http://javascript.crockford.com/code.html 作者:Douglas Crockford 译文:http://www.yeeyan.com/articles/ ...
- 最棒的 JavaScript 学习指南(2018版)
译者注:原文作者研究了近2.4万篇 JavaScript 文章得出这篇总结,全文包含学习指南.新人上手.Webpack.性能.基础概念.函数式编程.面试.教程案例.Async Await.并发.V8. ...
随机推荐
- Java项目:学生成绩管理系统(一)
学生成绩管理系统(一) 项目名称:学生成绩管理系统 项目需求分析(Need 需求): (1)该系统的用户分为教师和学生.教师的功能有:管理某一学生或课程的信息以及成绩,包括增.删.查.报表打印等:学生 ...
- 简单学会.net remoting
简介 •.net remoting是.net在RPC分布式应用的技术.首先,客户端通过 remoting访问通道以获得服务端对象,再通过代理解析为客户端对象,通过通道来实现远程对象的调用. 原理 •远 ...
- Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况
转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...
- 【思路】-OctService服务类
OctService服务类 从以下几个方面来说吧,这次说的会有点长啊 设计: 思路: 作用: 目的: 问题: 为什么要设计这个? 它解决了什么问题? 是什么? 为什么? 怎么样? OctService ...
- JQUERY MOBILE 中文API站 和 官方论坛
中文API站:http://www.jqmapi.com/api1.2/preview/quickstartquide.html 官方论坛:http://bbs.phonegapcn.com/foru ...
- telnet 使用
Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用telnet程序,用它连接 ...
- 【软件工具】Driver Booster3永久激活法
原作者網址:erik2041999 (YouTube) 1.安装Driver Booster3 (档案已附) 2.使用此启动码0187E-B9764-4D9FA-211B3断网启动 3.保持断网状态并 ...
- c++学习笔记1
1.explicit 防止隐式类型转换 2.cbegin() cend()等价于返回 const_iterator 类型 3.it->mem 等价于 (*it).mem 4.不允许使用一个数组初 ...
- Secondary NameNode:的作用?
前言 最近刚接触Hadoop, 一直没有弄明白NameNode和Secondary NameNode的区别和关系.很多人都认为,Secondary NameNode是NameNode的备份,是为了防止 ...
- truncate,delete,drop的异同点
说明:本文摘自oracle技术用户讨论组 truncate,delete,drop的异同点 注意:这里说的delete是指不带where子句的delete语句 相同点:truncate和不带w ...