JavaScript笔记(二)

 

这篇记录函数的用法

标准函数定义:

    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; }

 

你可能感兴趣的:(JavaScript)