文章目录
内置函数、函数基本用法
内置函数
特定计算eval();
计算表达式的结果,支持简单表达式,带变量表达式,条分支表达式以及用于解析JSON格式字符串
例:
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();
在我的第5篇笔记JavaScript数据类型转换有详细的描述.
判断函数
1.isNaN():
作用:检查其参数是否非数字(注意是检查是否为非数字,非数字,非数字)。
如果是非数字就返回true(意思就是如果这个参数不是数字类型的就返回true),
如果不是非数字就返回false(意思就是如果这个参数是数字,就返回false)。
2.isFinite():
判断是否是有限数字(或者可以转换有限数字),如果是则返回true,如果是NaN、或者是正负无穷大数则返回false。
编解码函数
其意思为:对特殊字符串进行编码以及对编码过的字符串进行解码。
encodeURI,decodeURI
使用ISO8859-1的encodeURI,decodeURI:
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=18;
f1();
// 完毕*/
例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的声明方法,让这个代码执行的时候有一个特殊的情况。输出为:9、9、报错找不到a、9、9、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
注:此为个人学习笔记,如有补充可以选择在评论区留言或者无视。