【JS学习笔记】9.JavaScript函数基础(内置函数、函数基本用法、做用域、回调函数、匿名函数)

内置函数、函数基本用法

内置函数

特定计算eval();

计算表达式的结果,支持简单表达式,带变量表达式,条分支表达式以及用于解析JSON格式字符串javascript

例:前端

var str="5+5";
		console(eval(str));

		var exp=prompt('请输入一个表达式:');
		var x=5,y=5;
		var result=eval(exp);
		console.log(result);

类型转换函数

1.parseInt()
2.parseFloat();java

在个人第5篇笔记JavaScript数据类型转换有详细的描述.数组

判断函数

1.isNaN():函数

做用:检查其参数是否非数字(注意是检查是否为非数字,非数字,非数字)。
若是是非数字就返回true(意思就是若是这个参数不是数字类型的就返回true),
若是不是非数字就返回false(意思就是若是这个参数是数字,就返回false)。学习

2.isFinite():this

判断是不是有限数字(或者能够转换有限数字),若是是则返回true,若是是NaN、或者是正负无穷大数则返回false。编码

编解码函数

其意思为:对特殊字符串进行编码以及对编码过的字符串进行解码。url

encodeURI,decodeURI

使用ISO8859-1的encodeURI,decodeURI:spa

ISO8859-1:每一个UTF-8的汉字编码成3个16进制字节,如:%字节1,%字节2,%字节3

例:

var str="我是jackson";
		var s1=encodeURI(str); //编码
		console.log(s1); //%E6%88%91%E6%98%AFjackson
		var s2=decodeURI(s1);//解码
		console.log(s2);//'我是jackson'
escape、unescape

escape、unescape使用的是unicode

unicode:每一个UTF-8的汉字被编码成一个双字节16进制转义字符,如:%u****,中文的范围是%u4e00至%u9fa5

例:

var s3=escape(str); //编码
		console.log(s3); //%u6211%u662Fjackson
		var s4=unescape(s3);//解码
		console.log(s4);//'我是jackson'

二者区别:escape会对双字节和符号";/;@&=+$,-_.~*’()"进行转换,而encodeURI不会

函数基础

建立、调用函数

建立方法

funchiton 函数名(参数1,参数2.....){
	函数体;
}

建立函数时的参数,称为形参。

调用方法:

函数名(参数1,参数2.....);

调用函数时的参数,称为实参

定义一无参个函数

function calcsum(){
			var sum=0;
			for(i=1;i<=100;i++){
				sum+=i;
			};
			console.log(sum);
		};
		// 调用函数
		calcsum();

定义单个形参的函数

function calcsum2(n){//n为形参
			var sum=0;
			for(i=1;i<=n;i++){
				sum+=i;
			};
			console.log('从1到'+n+'之和为:'+sum);			
		};
		// 调用函数
		calcsum2(1000);//1000为实参

定义多个形参的函数

function calcsum3(m,n){//m,n为形参
			var sum=0;
			for(i=m;i<=n;i++){
				sum+=i;
			};
			console.log('从'+m+'到'+n+'之和为:'+sum);			
		};

		// 调用函数
		calcsum3(1000);

函数的用法

1.在JavaScript中,实参的个数能够和形参个数不想等
能够看一下案例

function show(name,age){
			console.log('我是的姓名是:' +name + ',年龄为'+age);
		};
		
		show('jackson',26);//我是的姓名是:jackson,年龄为26 
			
		show('jackson');//我是的姓名是:jackson,年龄为undefined
		
		show();//我是的姓名是:undefined,年龄为undefined
		
		show('jackson',26,'男');//我是的姓名是:jackson,年龄为26 

2.JavaScript,中没有重载的概念,若是函数同名后面的函数会把前面的函数覆盖掉

注:在其余语言中,会有重载的概念,即函数名相同,参数个数不一样的多个同名函数

例:

function calc(num1,num2,num3){
			console.log(num1*num2*num3);
		};

		function calc(num1,num2){
					console.log(num1+num2);
		};

		calc(3,5);//8
		calc(2,2,3);//4
		calc(4);//NaN
		calc(4,4,4,3);//8

函数返回值

函数执行后能够返回一个结果,称为函数的返回值
使用return关键字来返回函数执行后的结果值

function calcSum(num1,num2){
			// console.log(num1+num2);
			var sum=num1+num2;
			return sum;//使用return关键字返回函数执行后的结果
		};
		var result=calcSum(3,5);
		console.log(result*2);
		console.log(result/2);

若是return后面没有返回值,或者没有使用return关键字,则默认返回undefined

function calcSum2(num1,num2){
			console.log(num1-num2);
		};
		calcSum2(5,2);//3
		var result=calcSum2(5,2);
		console.log(result);//undefined

return关键字的做用:

1.回函数的执行结果
2.结束函数的执行

例:

function calcSum3(num1,num2){
			console.log(num1+num2);
			return;
			console.log('return后面的代码!');//return后面的代码都不会执行
		};

		calcSum3(7,2);

练习

1.计算从到1指定数字之和,最多统计到8的总和。

function calcSum4(num){
			var sum=0;
			for(var i = 1;i<=num;i++){
				if(i>8){//若是大于8,直接返回当前和,再也不执行。
					return sum;
				};
				sum+=i;
			};
			return sum;
		};

		console.log(calcSum4(7));//28
		console.log(calcSum4(8));//36
		console.log(calcSum4(9));//36

2.计算两数之和,若是总和大于20,则直接中止,不然输出总和

function calcSum5(num1,num2){
			var sum=num1+num2;
			if(sum>20){
				return;
			};
			console.log(sum);
		};

		calcSum5(3,16);//19
		calcSum5(4,18);//无输出*/

		//练习1:求个数的最大值
		/*function max(num1,num2){ if(num1>num2){ return num1; }else if(num2>num1){ return num2; }else{ return '两数相等'; }; } var x=prompt('请输入第一个数'); var y=prompt('请输入第二个数字'); var maxNumber=max(x,y); document.write('最大值为:'+ maxNumber ); 

函数的参数

对函数的参数进行处理:

function calcSum(num1,num2){
			//若是参数为undefined、null、NaN时,则默认设置为0
			/*if(!num1){ num1=0; } if(!num2){ num2=0; } num1=num1||0; num2=num2||0; //若是参数为非空字符串,则提示用户将进行拼接 if(isNaN(num1)||isNaN(num2)){ console.log('将进行拼接操做:'); }; var sum=num1+num2; console.log(sum); }; calcSum(3,6);//9 calcSum(5);//undefined calcSum(5,null);//5 calcSum(5,"");//'5' calcSum(5,NaN);//NaN calcSum(5,'hello');//5hello 

变量的做用域

即变量能够在上面位置使用
分类:局部变量、全局变量

局部变量:在函数内声明的变量,只能在该函数内访问,函数运行结束,变量自动销毁。
全局变量:只要不是在函数内部声明的变量,在任何位置均可以访问,当全部页面关闭时销毁。

注:在函数内没用使用var声明的,而且直接赋值的变量,也是会提高为全局变量的

全局变量
var name='jackson';//全局变量,在任何位置均可以访问
		console.log(name);//jackson

		function show1(){
			console.log(name);
		};
		show1();//jackson
		function show2(){
			console.log(name);
		};
		show2();//jackson
局部变量
function show3(){
			var age=26; //局部变量,只有在该函数内才可用,函数结束后就会销毁
			console.log('name:'+name+' age:'+age)
		};
		show3();//
		function show4(){
			console.log('name:'+name+' age:'+age)
		};
		show4();//报错:age is not defined,由于show4找不到age,age在show3使用完后,就自动销毁了
function show5(){
			sex='male';
			//函数内建立的全局变量,即在函数内部未使用var声明,直接赋值的变量,也是全局变量。 *通常不建议怎么写
			console.log('name:'+name+' sex:'+sex);
		}
		show5();//name:jackson sex:male 
		function show6(){
			console.log('name:'+name+' sex:'+sex);
		}
		show6();//name:jackson sex:male
就近原则

若是局部变量和全局变量同名,默认访问的是局部变量,若是要访问全局变量,必须使用window前缀在必定条件下,也可使用this前缀

var hobby='前端';
		function show(){
			var hobby='吃饭';
			console.log('局部变量:'+hobby);//局部变量:吃饭
			console.log('全局变量:'+window.hobby);//全局变量:前端
			console.log('全局变量:'+this.hobby);//全局变量:前端

		};
		show();
JavaScript中没有块级做用域的概念

JavaScript中没有块级做用域的概念 ,只要不是在函数中定义的变量,都是全局变量,在其余语言中,一对花括号{}就是一个代码块,在代码块中定义的变量在代码块外是没法访问的。

在ES6中已经可使用let关键字进行定义变量,支持块级的做用域。

function show(){
			for(var i=1;i<=10;i++){
				var name='Jakcson';//局部变量
				console.log(name+'转圈圈+'+i)
			};
			console.log(name);//Jakcson,能够输出,JAVASCRIPT中没有块级做用域,只有全局和局部之分,其余语言会以花括号分割代码块。
		};
		show();
		console.log(name);//没有输出
		*/
		//在ES6中可使用let定义块级做用域的变量
		/*function show2(){ for(var i=1;i<=10;i++){ // var name='Jakcson';//局部变量 let name='CYA' console.log(name+'转圈圈+'+i) }; console.log(name);//没法输出,let }; show2(); 

练习

1.求圆的面积

function circleArea(radii){
			pi=Math.PI;
			var area=pi*pi*radii*radii;
			return area;
		};
		var radius=Number(prompt('请输入圆的半径(单位:cm)'));
		var area=parseInt(circleArea(radius));
		document.write('该圆的半径为:'+radius+'厘米</br>'+'面积约为:'+area+'平方厘米');

2.圆的周长

function circumference(radii){
			pi=Math.PI;
			var perimeter=2*(pi*radii);
			return perimeter;
		};
		var perimeter=parseInt(circumference(radius));
		document.write('</br>该圆的直径为:'+(2*radius)+'厘米</br>'+'周长约为:'+perimeter+'厘米');

3.求2个数的最大值

function maxNum1(num1,num2){
			if(num1>num2){
				return num1;
			}else if(num2>num1){
				return num2;
			}else{
				return '两数相等';
			};
			return num1>num2?num1:num2;
		}*/

		/*var x=prompt('请输入第一个数'); var y=prompt('请输入第二个数字'); var maxNumber=max(x,y); document.write('最大值为:'+ maxNumber ); 

4.求3个数的最大值

function maxNum2(num1,num2,num3){
			return (num1>num2?num1:num2)>num3?(num1>num2?num1:num2):num3;
		};
		var x=Number(prompt('请输入数字x'));
		var y=Number(prompt('请输入数字y'));
		var z=Number(prompt('请输入数字z'));
		var result=maxNum2(x,y,z);
		document.write('其中最大的数为:'+result);

固然咱们也能够利用练习3中的函数来进行函数嵌套

function maxNum2(num1,num2,num3){
			var temp=maxNum1(num1,num2);
			return maxNum1(temp,num3);
		};
		var x=Number(prompt('请输入数字x'));
		var y=Number(prompt('请输入数字y'));
		var z=Number(prompt('请输入数字z'));
		var result=maxNum2(x,y,z);
		document.write('其中最大的数为:'+result);

5.求数组中的最大值,函数接收一个数组

function maxNum3(array){
			var max=array[0];
			for(var i=0;i<array.length;i++){
				if(array[i]>max){
					max=array[i];
				};
			};
			return max;
		};
		var nums=[213,12,4,2,12,56,34,299];
		document.write('最大值为:'+maxNum3(nums));

6.将数组反转后,返回反转后的数组

function reverse(array){
			var newArray=[];
			for(var i=array.length-1;i>=0;i--){
				newArray[newArray.length]=array[i];
			};
			return newArray;
		};
		var nums=[213,12,4,2,12,56,34,299];
		document.write('新数组为'+reverse(nums));

变量提高

咱们首先来了解一下解析器在执行JavaScript代码的过程:
1.首先进行预解析(全局做用域)
将变量的var和函数function的声明提早到做用域的最上面,须要注意的是变量的赋值操做是不会提早的,这步也就是变量提高。
2.执行代码
执行规则就是常规的从上至下,逐行执行代码
当执行到函数时,就会进入函数内部进行内部的预解析(局部做用域)
3.局部的预解析
也就将声明部分提高到函数的最上面先执行
而后从上往下,逐行执行代码。
好比如下代码:

var num=10;
		fun();
		function fun(){
			console.log(num);
			var num=20;
		};

按照正常的JS逐行执行顺序来看,看上去输出值不是提示报错就是10,对吧?不对,输出应该是undefined
咱们来看下拆解的执行步骤:

// 第一步:预解析(全局做用域)
		/*var num; function fun(){ //第三步:当执行函数的时,再次进行预解析(局部做用域) var num; // 第四部:一行一行执行代码 console.log(num);//因此执行到这里输出的时候,输出了一个函数内部声明了可是未赋值的num num=20; }; //第二步:一步一步执行代码 num=10; fun(); //完毕 

注意:正确的顺序是跟着标签的顺序进行执行的。

例2:

var a=18;
		f1();
		function f1(){
			var b=9;
			console.log(a);//undefined
			console.log(b);//9
			var a='123';
		};

拆解步骤:

// 第一步:预解析(全局做用域)
		var a;
		function f1(){
			//第三步:函数内部预解析
			var b;
			var a;

			//第四步:执行函数内部
			b=9;//给b赋值
			console.log(a);//执行了函数内部声明可是未赋值的a,因此是undefined
			console.log(b);//执行了输出b,而且b被赋值了9,因此输出9
			a='123';
		};

		// 第二步:执行代码
		a=18f1();
		// 完毕*/

例3:

f1();
		console.log(c);
		console.log(b);
		console.log(a);
		function f1(){
			var a=b=c=9;
			console.log(a);
			console.log(b);
			console.log(c);
		};

这里我本身踩了个坑,由于教学在这步骤的时候直说了同上,可是其中的var a=b=c=9的声明方法,让这个代码执行的时候有一个特殊的状况。输出为:九、九、报错找不到a、九、九、9。
详细的步骤:

// 第一步:预解析(全局做用域) 
		function f1(){
			// 第三步:函数内部预解析
			var a;
			//第四步:执行函数内部
			c=9;//提高
			b=c;//提高
			a=b; 这里有个特殊状况,由于在函数中var a=b=c的写法,致使只有a被声明了,b和c没有在函数中被声明,因此被自动解析为全局变量了。
			console.log(a);
			console.log(b);
			console.log(c);
		};
		// 第二步:一步一步执行代码
		f1();
		console.log(c);
		console.log(b);
		console.log(a);
		// 完毕!

一开始踩坑觉得开头的输出cba都是没法被找到,由于在预解析中,是没有全局变量的,并且运行的结果却和我一开始想象的不太同样,直到我翻阅了资料才了解到,当在var 后面使用=链接的时候,只会对第一个变量进行声明,后面几个变量只是普通的赋值操做而已,当他们被放进函数中,普通的赋值操做,就使他们变成了全局变量。
也就是说,当var a=b=c=9是不等于var a=9;var b=9;var c=9;
而应该是var a;c=9;b=c;a=b;
当这就很明显了,在函数里的时候c=9;b=c;至关于一个把变量提高到了全局,并且只有a是被var 声明过了,致使在执行以后,c和b都能找到,可是a是在函数里声明的是局部变量,全局中没有这个变量因此是a is not defined

定义函数的形式、回调函数

方式1:函数声明

function sum(num1,num2){
			return num1+num2;
		}
		console.log(sum(3,7));

方式2:函数表达式

var sum=function(num1,num2){ //没有名字的函数,称为匿名函数
			return num1+num2;
		};
		console.log(sum(4,8));

区别:

fn1();//能够被执行,由于会预解析函数,也就是能够先调用,再声明
		function fn1(){
			console.log('this is fn1');
		}
		
		fn2();//没法执行,会提示fn2不是函数
		function fn2(){
			console.log('this is fn2');
		};

回调函数

顾名思义,不当即执行的函数条用,知足必定条件时才执行佛者别的代码条用执行
用法:条用时只写函数名,没有小括号()和参数
应用场景:事件绑定,函数参数

function show1(){
			document.write('这是第一个函数');
		}

		function show2(){
			document.write('这是第二个函数');
		}

		//当点击页面时执行函数show2
		// window.οnclick=show2();//页面加载完就直接执行了,可是点窗体又不执行。
		window.onclick=show2;//这样就能够按预想的方式执行,称为回调函数:即回头再调用此函数

函数也是一种数据类型

函数也是一种数据类型,其类型为function类型

function fn(){
			console.log('这是一个函数');
		}

		console.log(typeof fn);//function

		var fn2=function(){
			console.log('这是一个函数2');
		};
		console.log(typeof fn2);//function

将函数做为参数:

function show(a,fn){
			console.log(a);
			fn();//调用传入的函数
		};

		show(8,fn);//8,这是一个函数

例2:

function sum(x,y){
			return x+y;
		}

		function sum2(a,b,fn){
			var result=fn(a,b);
			console.log(result);
		};

		sum2(1,2,sum);//3

匿名函数

用于回调

引用以前的回调函数:

function show(){
			console.log('点击了页面');
		}
		window.onclick=show;

可使用匿名函数来写:

window.onclick=function(){//匿名函数,用于回调
			console.log('点击了页面2!')
		};

用于一次性执行的函数:

(function(){
			console.log('只用于一次执行1')
		})();

这种写法其实就是一个调用,只是把调用的函数名直接匿名函数的方式完整的写出来。
好比咱们用下以前的函数做为数据类型的例子2:

function sum(x,y){
			return x+y;
		}

		function sum2(a,b,fn){
			var result=fn(a,b);
			console.log(result);
		};

		sum2(1,2,sum);//3

咱们把他sum
这步骤去掉,直接用匿名函数写到实参里。

function sum2(a,b,fn){
			var result=fn(a,b);
			console.log(result);
		};
		sum2(1,2,function(x,y){//将匿名函数做为另外一个函数的参数
			retrun x+y;
		});//3

注:此为我的学习笔记,若有补充能够选择在评论区留言或者无视。

相关文章
相关标签/搜索