1、Array类型函数
array.concat(item...)
函数功能:关联数组,实现数组相加功能,但并不影响原先数组,concat返回新数组。
array.join(separator)
函数功能:将array中的每个元素用separator为分隔符构造成字符串,默认的separator是逗号,当然你可以自己指定separator
事实上join方法最常用的地方在字符串相加,用过js的人都知道js的字符串相加是特别慢且性能特别差的,把大量片段字符串放在一个数组中并用join方法连接比用+连接要快得多。
array.pop()
pop和push方法使数组array像堆栈一样工作。
函数功能:pop方法移除array中的最后一个元素并返回该元素。
如果array是空的,则返回undefined;
array.push(item...)
函数功能:push方法将一个或多个item参数附加到array尾部。但是它不像concat方法那样,push方法不会修改item参数,如果参数item是一个数组,它会将参数数组作为单个元素整个添加到数组中,它返回array的新长度
array.reverse()
函数功能:反转array中元素的顺序,返回当前array
array.shift()
函数功能:移除array中的第一个元素并返回该元素,如果array是空的,它会返回undefined。
shift比pop要慢很多
array.slice(start,end)
函数功能:对array中的一段做浅复制。end参数是可选的,默认值为数组的长度array.length。
如果两个参数中任何一个是负数,array.length将和它们相加来试图将它们成为非负数。
如果start大于等于array.length,得到的结果将是一个新的空数组
array.sort(compareFn)
函数功能:对array中的内容进行排序。
var n = [4, 8, 15, 16, 23, 43];
n.sort(function (a, b) {
return a - b;
});
console.log(n); //[4, 8, 15, 16, 23, 43]
var m = ['aa', 'bb', 'a', 4, 8, 15, 16, 23, 43];
m.sort(function (a, b) {
if (a === b) {
return 0;
}
if (typeof a === typeof b) {
return a < b ? -1 : 1;
}
return typeof a < typeof b ? -1 : 1;
});
console.log(m); //[4, 8, 15, 16, 23, 43, "a", "aa", "bb"]
var compare = function (name) {
return function (o, p) {
var a, b;
if (typeof o === 'object' && typeof p === 'object' && o && p) {
a = o[name];
b = p[name];
if (a === b) {
return 0;
}
if (typeof a === typeof b) {
return a < b ? -1 : 1;
}
return typeof a < typeof b ? -1 : 1;
} else {
throw {
name: "Error",
message: 'Expected an object when sorting by ' + name
};
}
};
};
var s = [
{ first: 'Joe', last: 'Felix' },
{ first: 'Moe', last: 'Besser' },
{ first: 'Joe', last: 'Howard' },
{ first: 'Shemp', last: 'DeRita' },
{ first: 'Larry', last: 'Howard' },
{ first: 'Curly', last: 'Fine' },
{ first: 'Shirly', last: 'Angela' } ]; s.sort(compare('first'));
/*
s = [
{ first: 'Curly', last: 'Fine' },
{ first: 'Joe', last: 'Felix' },
{ first: 'Joe', last: 'Howard' },
{ first: 'Larry', last: 'Howard' },
{ first: 'Moe', last: 'Besser' },
{ first: 'Shemp', last: 'DeRita' },
{ first: 'Shirly', last: 'Angela' }
];
*/
array.splice(start,deleteCount,item...)
函数功能:从array中移除1个或多个元素,并用新的item替换它们。返回一个包含移除元素的数组。
array.unshift(item...)
函数功能:将item插入到array的开始部位。返回array的新长度值。
2、Function类型函数
function.apply(thisArg,argArray)
Function.prototype.bind = function (that) {
//返回一个函数,调用这个函数就像它是那个对象的方法一样
var method = this,
slice = Array.prototype.slice,
args = slice.apply(arguments, [1]);
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0])));
};
};
var x = function () {
return this.value;
} .bind({ value: 666 });
console.log(x());//
3、Number类型函数
number.toExponential(fractionDigits)
函数功能:把number转换成一个指数形式的字符串。可选参数fractionDigits控制其小数点后的数字位数,它的值必须在0到20之间。
number.toFixed(fractionDigits)
函数功能:把number转换成一个十进制形式的字符串。可选参数fractionDigits控制其小数点后的数字位数,它的值必须在0到20之间。默认为0。
number.toPrecision(precision)
函数功能:把number转换成一个十进制形式的字符串。可选参数fractionDigits控制其小数点后的数字位数,它的值必须在1到21之间。
number.toString(radix)
函数功能:把number转换成一个字符串。可靠参数radix控制基数,它的值必须在2和36之间,默认为10
4、Object类型函数
object.hasOwnProperty(name)
函数功能:如果object包含名为name的属性,hasOwnProperty方法将返回true,原型链中的同名属性是不会被检查的。
for (name in obj) {
if (obj.hasOwnProperty(name)) {
console.log(obj[name]);
}
}
5、Regexp类型函数
regexp.exec(string)
函数功能:成功匹配regexp和字符串,返回一个数组。
数组中下标为0的元素包含正则表达式regexp匹配的子字符串
下标为1的元素是分组1捕获的文本,下标为2的元素是分组2捕获的文本,依此类推。如果匹配失败,就返回null。
如果regexp带有一个g(全局)标志,查找不是从这个字符串起始位置开始,而是从regexp.lastIndex(它的初始值为0)位置开始,如果匹配成功,那么regexp.lastIndex将被设置为该匹配后第一个字符的位置。 不成功的匹配会重置regexp.lastIndex为0
regexp.test(string)
函数功能:如果regexp匹配string,返回true 否则返回false
6、String类型函数
string.charAt(pos)
函数功能:返回在string中pos位置处的字符。
如果pos小于0或者大于string.length,将返回空字符串
string.charCodeAt(pos)
函数功能:返回在string中pos位置处的字符的字符编码。
string.concat(string...)
函数功能:连接字符串(不过很少被使用,因为用运算符+也能实现这个功能)
string.indexOf(searchString,position)
函数功能:在string内查找另一个字符串searchString,如果找到则返回第一个匹配字符的位置,否则返回-1。
可选参数position可设置从string的某个位置开始查找。
string.lastIndexOf(searchString,position)
函数功能:跟indexOf方法类似,区别是从字符串的末尾开始查找而不是从开头。
string.localCompare(that)
函数功能:比较两个字符串
string.match(regexp)
函数功能:匹配一个字符串和一个正则表达式。
如果没有g标识,string.match(regexp)和regexp.exec(string)结果相同。
如果有g标识,返回一个包含除捕获分组之处的所有匹配的数组。
string.replace(searchValue,replaceValue)
函数功能:对string进行查找和替换操作,并返回一个新的字符串。
var oldAreaCode = /\((\d{3})\)/g;
var p = '(555)(666)-1212'.replace(oldAreaCode, '$1-');
console.log(p);//555-666--1212
string.search(regexp)
函数功能:和indexOf方法类似,只是它接受一个正则表达式作为参数而不是一个字符串,如果找到匹配返回第一个匹配的首字符位置,如果没有找到匹配,则返回-1。
string.slice(start,end)
函数功能:复制string的一部分来构造一个新的字符串。
如果start参数是负数,它将与string.length相加。end参数是可选的,并且它的默认值是string.length。如果end参数是负数,它将与string.length相加。end参数是一个比最末一个字符的位置值还大的数。
string.split(separator,limit)
函数功能:把string分割成片段来创建一个字符串数组。可选参数limit可以限制被分割的片段数量。
var digits = '0123456789';
var a = digits.split('', 5); //["0", "1", "2", "3", "4"]
string.substring(start,end)
函数功能:substring的用法和slice方法一样,只是它不能处理负数参数,一般性的用slice替代它。
string.toLocalLowerCase()
函数功能:用本地化的规则把string中的所有字母转换为小写格式。
string.toLocalUpperCase()
函数功能:用本地化的规则把string中的所有字母转换为大写格式。
string.toLowerCase()
函数功能: 把string中的所有字母都转化为小写格式。
string.toUpperCase()
函数功能: 把string中的所有字母都转化为大格式。
string.fromCharCode(char...)
函数功能:从一串数字中返回一个字符串。
var a = String.fromCharCode(67, 97, 116);
console.log(a);//Cat;
书写可读性的JavaScript
可读性的大部分内容都是和代码缩进相关的,必须保证代码有良好的格式。可读性的另一方面就是注释,一般而言,有如下一些地方需要进行注释
1.1.1 函数和方法
每个函数或方法都应该包含一个注释,描述其目的和用于完成任务所可能使用的算法,陈述事先的假设也非常重要,如参数代表什么,函数是否有返回值等等
1.1.2 大段代码
用于完成单个任务的多行代码应该在前面放一个描述任务的注释
1.1.3 复杂的算法
如果使用了一个独特的方式解决某个问题,则要在注释中解释你是如何做的,这不仅仅可以帮助其它浏览你代码的人,也能在下次你自己查阅代码的时候帮助理解
1.1.4 Hack
因为存在浏览器差异,JavaScript代码一般会包含一些Hack,不要假设其他人在看代码的时候能够理解Hack所要应付的浏览器问题,如果因为某种浏览器无法使用普通的方法,所以你需要用一些不同的方法,那么请将这些信息放在注释中。
1.1.5 代码排版
1.1.5.1 行长度
每行代码应小于 80 个字符。如果代码较长,应尽量选择换行,下一行代码应缩进4 个空格。这样可以使代码排版整齐,减轻阅读代码的疲劳感,以增强代码的可阅读性
1.1.5.2 行结束
JavaScript 语句应该以分号结束。但大多数浏览器允许不写分号,只要在本应是分号的地方有一个换行符就行。但是如果代码行较长需要换行的时候,有哪些注意事项呢?换行应选择在操作符和标点符号之后,最好是在逗号','之后,而不要在变量名、字符串、数字、或')' ']' '++' '--'等符号之后换行。这样可以有效的防止拷贝、粘贴而引起的错误,并可有效地增强代码的可阅读性。
例如:var valueB = valueA ///bad
+1;
可以替换为:var
valueC = valueB + ///good
valueA;
1.1.5.3
注释
我们会强调代码中注释数量的多少,而轻视了对注释质量的提高。编码是及时添加注释,会给后续代码的维护人员带来很大的便利。但是如果注释不注意更新,或者由于拷贝、粘贴引起的错误的注释,则会误导阅读人员,反而给阅读带来障碍,除了注释要及时更新外,我们还应对注释的内容要特别关注。注释要尽量简单、清晰明了,避免使用含混晦涩的语言,同时着重注释的意义,对不太直观的部分进行注解。
例如:
//following section is used to
initialize golbal variables
(good)
var valueA = 0; //initialize valueA to be sero (bad)
var valueB = 1;
...
//call f1 function after waiting for 50
seconds. (good)
setTimeout (f1,50000); //set timeout to be
20s (copy error)
大功能块的功能描述:
/*
*@desc:功能描述
*@param:参数描述
*@return:返回值
*/
1.1.5.4
缩进
建议使用4个空格来进行缩进
1.1.5.5
空白符
适当的空白行可以大大提高代码的可阅读性,可以使代码逻辑更清晰易懂。同时,在表达式中适当的留空白,也会给代码的阅读带来方便,关键字的后面如有括号,则最好在关键字和左括号'('之间留空白,如 for, if, while 等。而函数名和括号之间则不宜留空白,但若是匿名函数,则必须在
function 和左括号'('之间留空白,否则,编辑器会误认为函数名为
function。在表达式中,二元运算符
( 除左括号'(',左方括号'[',作用域点'.')
和两个操作数之间最好留空白。一元运算符(若不是词
typeof 等)和其操作数之间不宜留空白。逗号','的后面需要留空白,以显示明确的参数间隔,变量间隔等。分号';'之后通常表明表达语句的结束,而应空行。在
for 的条件语句中,分号之后则应该留空白。
总结一句就是缩进和注释可以带来更可读的代码,还有就是用空行来将逻辑相关的代码块分割开可以提高程序的可读性,增加程序的可读性只为了在未来代码更容易维护。
1.2
变量和函数命名
JavaScript是严格区分大小写的,名称的也遵循以下规则:
- 第一个字符必须是字母、下划线、或一个美元符号$
- 其它字符可以是字母、下划线、美元符号或数字
- 变量、参数、成员变量、函数等名称均以小写字母开头,构造器的名称以大写字母开头
- 下划线'_'开头的变量一般习惯于标识私有/局部成员
- 美元符号'$'开头的变量习惯于标识系统相关,比如系统进程等。应避免用下划线'_'或美元符号'$'来命名标识符。尽可能地降低代码的阅读负担
每一行最多只包含一条语句,必须将分号放在简单语句的结尾外,虽然分号在JavaScript是可有可无了,但是为了压缩后不容易报错,强制性的必须每条js代码都得以分号结束
1.2.1
变量名应为名词
如car或person,如果是私有变量,则在名称前加_下划线
1.2.2
函数名应该为动词开始
如getName(),返回布尔类型值的函数一般以is开始,如isEnable(),如果是普通函数,则第一个字母小写,如果是构造函数,则第一个字母大写。函数名与((左括号)之间不应该有空格。)(右括号)与 开始程序体的{(左大括号)之间应插入一个空格,}(右大括号)应该与函数名在同一行而不应该另起一行
1.2.3
变量和函数都应使用合乎逻辑的名字
不要担心长度,长度问题可以通过处理和压缩
1.2.4
所有变量声明都需要放到函数最顶部声明或者说是作用域开始部位声明
1.3
变量类型透明
因为JavaScript是弱类型(也叫松散类型)语言,很容易忘记变量所应包含的数据类型。使用匈牙利标记法来指定变量类型,匈牙利标记法就是在变量名之前加上一个或多个字符来表示数据类型。JavaScript中最传统的匈牙利标记法是用单个字符表示基本类型:“O”代码对象,“S”代表字符串,“I”代表整数,“F”代表浮点数,“B”代表布尔型。如下所示
var
bFound; //布尔型
var
iCount; //整数
var
sName; //字符串
var
oPerson; //对象
简单几句话来说就是:
1:样式与javascript分离
2:1、循环语句中length属性可以用变量保存。2、为事件处理器创建重用的函数。
3:使用配置对象存放代码中的硬编码,如使用到的文本标签或自定义的属性名。有利于后续的维护。
4:为变量和函数起有含义的名字
5:添加必要的注释
JavaScript变量声明的浅谈
相对于C/C++来说,ECMAScript里的for循环并不能创建一个局部的上下文。
for (var k in {a: 1, b: 2}) {
alert(k);
}
alert(k); // 尽管循环已经结束但变量k依然在当前作用域
任何时候,变量只能通过使用var关键字才能声明。
上面的赋值语句:
a = 10;
这仅仅是给全局对象创建了一个新属性(但它不是变量)。“不是变量”并不是说它不能被改变,而是指它不符合ECMAScript规范中的变量概念,所以它“不是变量”(它之所以能成为全局对象的属性,完全是因为javascript中存在一个global对象,这样的操作不是声明一个变量而是给global对象增加一个a属性。
下面看一个简单的例题来说明问题
if (!("a" in window)) {
var a = 1;
}
alert(a);
首先,所有的全局变量都是window的属性,语句 var a = 1;等价于window.a = 1;
你可以用如下方式来检测全局变量是否声明
"变量名称" in window
第二,所有的变量声明都在范围作用域的顶部,看一下相似的例子:
alert("a" in window);
var a;
此时,尽管声明是在alert之后,alert弹出的依然是true,这是因为JavaScript引擎首先会扫墓所有的变量声明,然后将这些变量声明移动到顶部,最终的代码效果是这样的:
var a;
alert("a" in window);
第三,你需要理解该题目的意思是,变量声明被提前了,但变量赋值没有,因为这行代码包括了变量声明和变量赋值。
你可以将语句拆分为如下代码:
var a; //声明
a = 1; //初始化赋值
所以总结起来就是当变量声明和赋值在一起用的时候,JavaScript引擎会自动将它分为两部以便将变量声明提前,不将赋值的步骤提前是因为他有可能影响代码执行出不可预期的结果。
题目中的代码相当于:
var a;
if (!("a" in window)) {
a = 1;
}
alert(a);
根据上述例题的分析,声明变量时如果是声明的局部变量前面一定要加var,如果声明的是全局变量可以不加var(最好限制全局变量的个数,尽量使用局部变量)
下面讲述一个使用var的几个特性
使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误。
如果重复使用的一个声明有一个初始值,那么它担当的不过是一个赋值语句的角色。
如果重复使用的一个声明没有一个初始值,那么它不会对原来存在的变量有任何的影响。
没有var声明的变量,是作为全局变量存在的;有var声明的变量,属于局部变量,尤其是在函数内部。并且,经过测试,带var声明比不带var速度要快。函数内尽量多设局部变量,这样即安全又快速,变量操作也更加合理,不会因为函数内胡乱操作全局变量而导致逻辑错误。
声明对象时最好使用对象自面量的方式,这样的速度相对new的方式要快很多。
变量名是自己取的,为了照顾语义和规范,变量名可能稍长,但是注意了,变量名的长度也会影响代码的执行速度。长的变量名声明的执行速度没有短的快。