这篇记录函数的用法
标准函数定义:
function sum(a, b) {
var c = a + b;
return c;
}
其中a和b叫做函数的参数,函数体内return c是将c作为返回值(如果没有显式的return,默认返回undefined),虽然函数只声明了两个参数,实际上调用的时候可以传入任意数量的参数,比如:sum(1,2,3,4,5),每个函数都会默认创建一个arguments变量,类似一个数组,可通过下标访问所有的参数
预定义的函数:
下面这些函数都是黑盒,无法查看内部实现代码
parseInt()
尝试把任意类型转换成整数,如果转换失败,返回NaN
一些示例:
parseInt('123') >>>123
parseInt('abc123') >>>NaN
parseInt('1abc23') >>>1
parseInt('123abc') >>>123
第二个参数表示进制
parseInt('FF', 10) >>>NaN
parseInt('FF', 16) >>>255 //十六进制
parseInt('0377', 10) >>>377
parseInt('0377', 8) >>>255 //八进制
对于0开头的字符串,parseInt会默认把它当成8进制转换,如:
parseInt('0377') >>>255
对于0x开头的字符串,parseInt会默认把它当成十六进制进行转换,如:
parseInt('0x377') >>>887
parseFloat()
尝试把参数转换成小数,只有1个参数,转换失败会返回NaN
区别:
parseInt("1.9")>>>1 parseFloat("1.9")>>>9
parseInt("1e2")>>>1 parseFloat("1e2")>>>100
parseFloat('1.23abc.00')>>>1.23
parseFloat('a.bc1.23') >>>NaN
isNaN()
判断参数是不是数字,如果不是数字,返回false,可以用来判断parseInt和parseFloat是否转换成功。
isNaN(NaN) >>>true
isNaN(123) >>>false
isNaN(1.23) >>>false
isNaN(parseInt('abc123')) >>>true
这个函数会尝试转换参数:
isNaN('1.23') >>>false
isNaN('a1.23') >>>true
isNaN('1px')>>>true //严格匹配,parseInt和parseFloat可以转换,但isNaN不认为它是个数字
因为NaN==NaN返回false,所以这个函数非常有用。
isFinite()
判断参数是一个数字,而不是Infinity或NaN
isFinite(Infinity) >>>false
与isNaN类似,它也会尝试转换字符串
isFinite("0") >>>true
encodeURI() /encodeURIComponent() ,decodeURI() /decodeURIComponent()
encodeURI会把参数当作一个完整的URI字符串处理
encodeURIComponent()会把参数当作URI的一部分,比如查询部分,所以所有的特殊字符都会被encode。
eval()
将参数当作一段javascript执行,不建议使用,会有性能和安全问题
变量作用域
在js中没有块作用域(不同于java),只有函数作用域和全局作用域
在函数内部定义的变量只有函数内或此函数的私有函数能访问,外部不能访问,如:
var global = 1;
function f() {
var local = 2;
global++;
return global;
}
global是全局的,在f内也可以访问,但是local是在f内定义的,不能被外部访问
注意,如果不小心丢掉了var关键字,local会被分配为全局变量
函数内的变量声明会覆盖全局声明:
var a = 123;
function f() {
alert(a); //undefined
var a = 1;
alert(a); //1
}
f();
函数也是数据(变量),两种定义方式:
function f(){return 1;} //函数声明
var f = function(){return 1;} //函数表达式
typeof f>>>"function"
完全可以把函数当作普通变量处理,让一个新变量指向它,当作参数传递,当作返回值,或者干脆delete f
匿名函数:
~function(a){alert(a)}(1);//定义一个匿名函数并马上执行它
私有函数
function a(param) {
function b(theinput) {
return theinput * 2;
};
return 'The result is ' + b(param);
};
其中b就是一个private function
或者用函数表达式的方式:
var a = function(param) {
var b = function(theinput) {
return theinput * 2;
};
return 'The result is ' + b(param);
};
综合应用,重写自己:
function a() {
alert('A!');
a = function(){
alert('B!');
};
}
只有第一次执行a时才会alert('A!'); 适合做一些只做一次的初始化工作
或者:
var a = function() {
function someSetup(){
var setup = 'done'; //马上会被执行,因为函数最后有一对小括号
}
function actualWork() {
alert('Worky-worky');
}
someSetup();
return actualWork;
}();
闭包
关于闭包的概念,网上有很多介绍的很多,在这不解释意义了,来几个例子,加深印象:
1、
function f(){
var b = "b";
return function(){
return b;
}
}
想在外部访问f的内部变量b,可以:
var n=f();
var b=n();
或者:
var n;
function f(){
var b = "b";
n = function(){ //n在外部声明
return b;
}
}
2、
function f(arg) {
var n = function(){
return arg;
};
arg++;
return n;
}
var m = f(123);
m();//结果是124
3、
function f() {
var a = [];
var i;
for(i = 0; i < 3; i++) {
a[i] = function(){
return i;
}
}
return a;
}
var a = f();
a[0]()=3,a[1]()=3,a[2]()=3
修正一下:
function f() {
var a = [];
var i;
for(i = 0; i < 3; i++) {
a[i] = (function(x){
return function(){
return x;
}
})(i);
}
return a;
}
var a = f();
a[0]()=0,a[1]()=1,a[2]()=2
或者:
function f() { function makeClosure(x) { return function(){ return x; } } var a = []; var i; for(i = 0; i < 3; i++) { a[i] = makeClosure(i); } return a; }