JavaScript第五天
函数的复习
函数:function语句的集合,就是将多个语句封装到一起。
函数的执行,要会自己遍历,遇见fn()执行语句,就要移交控制权。函数执行完毕之后,控制权又移交回来了。
函数声明头的提升,程序一开始就会有一个预解析的过程,程序会通看全部代码,把所有的函数名字都放到开头预习一下,程序自己知道了,页面上有这个函数定义。但是,函数表达式是不能预解析的。
//函数声明头的提升
fn(); //正常会弹窗,把调用写在前面,因为函数声明头会预解析。
fn2(); //报错。函数表达式是不能预解析的
function fn(){
alert("我是函数");
}
//函数表达式是不能预解析的
var fn2 = function(){
alert("我是函数2");
}
函数优先 : 如果同一个标识符,在程序中又是变量的名字,又是函数的名字,解析器会把标识符给函数。
var a = 1;
function a(){
alert("我是函数");
}
a();
//如果这样书写程序会报错
因为:在执行var a = 1之前,函数已经把function a()预解析了,程序就已经知道页面上有一个函数叫做a。但是开始执行程序之后,定义了一个变量a,所以标识符a,就又变成变量了。遇见function定义,程序会无视,因为已经预解析了。直到a()运行的时候,a就是变量,无法运行,报错。
函数表达式是无法进行函数预解析的会按照变量的方式进行解析
a();
var a = 1;
var a = function(){
alert("我是函数");
}
函数表达式是不会预解析的,所以预解析的就是变量a的定义,就是undefined,undefined是无法执行的。
变量预解析和函数预解析是不一样的,函数预解析会把整个函数体拿出来使用,但是变量只是把变量名拿出来了
alert(a);//只会弹出undefined因为只是把变量名提前解析了,内容并没有
var a = "张贺";
作用域
一个变量如果定义在了一个function里面,那么这个变量就是一个局部变量,只在这个function里面有定义。出了这个function,就如同没有定义过一样。
<script type="text/javascript">
function fn(){
var a = 1; //定义在一个函数里面的变量,局部变量,只有在函数里面有定义
console.log("我是函数里面的语句,我认识a值为" + a);
}
fn();
console.log("我是函数外面的语句,我不认识a" + a);
//这个时候函数外的a是无法输出的,因为a变量是一个局部变量
</script>
总结
-
在function里面的变量,叫做局部变量,只在function里面有定义,出了function是没有定义的。
-
定义在全局范围内的,没写在任何function里面的,叫做全局变量,都可以用
多层嵌套,如果有同名的变量,那么就会发生“遮蔽效应”
var a = 1; //全局变量
function fn(){
var a = 5; //就把外层的a给遮蔽了,这函数内部看不见外层的a了。
console.log(a); //输出5,变量在当前作用域寻找,找到了a的定义值为5
}
fn();
console.log(a); //输出1,变量在当前作用域寻找,找到了a的定义值为1
作用域链:一个变量在使用的时候得几呢?就会在当前层去寻找它的定义,找不到,找上一层function,直到找到全局变量,如果全局也没有,就报错。
在js中如果不写var默认就是全局变量
//就默认在这里var a;
function fn(){
a = 1; //这个a第一次赋值的时候,并没有var过,
//所以就自动的在全局的范围帮你var了一次
}
fn();
console.log(a);
告诉我们一个道理,变量要老老实实写var。
函数的参数会默认成为这个函数的局部变量
全局变量的作用
功能1:通信,共同操作同一个变量
var num = 0;
function add(){
num++;
}
function remove(){
num--;
}
功能2:累加,重复调用函数的时候,不会重置
var num = 0;
function baoshu(){
num++;
console.log(num);
}
baoshu(); //1
baoshu(); //2
baoshu(); //3
//如果num定义在baoshu里面,每次执行函数就会把num重置为0:
函数也有作用域
function 大
{
function 小
{
}
小(); //可以运行
}
(); //不能运行,因为小函数定义在了大函数里面,离开大函数没有作用域。
闭包
function outer(){
var a = 333;
function inner(){
console.log(a);
}
return inner; //outer返回了inner的引用
}
var inn = outer(); //inn就是inner函数了
inn(); //执行inn,全局作用域下没有a的定义
//但是函数闭包,能够把定义函数的时候的作用域一起记忆住
//能够输出333
这就说明了,inner函数能够持久保存自己定义时的所处环境,并且即使自己在其他的环境被调用的时候,依然可以访问自己定义时所处环境的值。
一个函数可以把它自己内部的语句,和自己声明时所处的作用域一起封装成了一个密闭环境,我们称为“闭包” (Closures)。
function outer()
{
var a = 222;
function inner()
{
alert(a);
}
return inner;
}
var inn = outer();
inn();
闭包在工作中是一个用来防止产生隐患的事情,而不是加以利用的性质。
因为我们总喜欢在函数定义的环境中运行函数。从来不会把函数往外挪。那为啥学习闭包,防止一些隐患。
闭包的性质
每次重新引用函数的时候,闭包是全新的。
也就是说,闭包每次被拿走从新被使用的时候是全新的
function outer(){
var count = 0;
function inner(){
count++;
console.log(count);
}
return inner;
}
var inn1 = outer();
var inn2 = outer();
inn1(); //1
inn1(); //2
inn1(); //3
inn1(); //4
inn2(); //1
inn2(); //2
inn1(); //5
无论它在何处被调用,它总是能访问它定义时所处作用域中的全部变量
数组
数组(array)是一个有序的数据集合。说白了,数组就是类型的组合(集合)
var a = [12,34,67,98];
数组里可以存储任何类型的数据,包括函数
function fun()
{
alert("s");
}
var arr = ["哈哈",fun,12,true,undefined];
console.log(arr[1]());
数组的使用方法
1:length
计算数组的项数
var a = [1,2,3,4,5];
alert(a.length);//这样就会输出5因为数组a里有5
//如果想输出一个数组里的最后一项就可以用length-1
alert(a[(a.length)-1]);
如果使用数组中不存在的下标,就会输出undefined
如果想指定数组只需要写上要指定的下标赋值即可
var a = [1,2,3,4,5];
a[5] = 78;//这样就可以给已经定义的数组赋值了
a[66] = 90; //还可以跳跃指定赋值
//那么此时其他没有指定的项目就是undefined。
如果跳跃赋值了,这个时候再用length检测,我们设置了下标为66的项,强制拉长了数组;
数组一旦缩小就不能放大,改为0就会清空数组
var a = [22,33,44,55,66];
a.length = 2;
console.log(a);
//那么这个a就会输出[22,33]
a.length = 5;
//这时候再把它还原为原始大小,里面还是会额没有的
a.lenght = 0;
//这时候a这个数组就清空了
变量中存储的引用类型其实是存储的地址
var a = [11,22,33,44];
var b = a;
b[0] = "张贺";
console.log(a);
//这个时候会发现,更改b的时候,a也会收到影响,这说明b里存储的并不是a,而是a的内存地址
- 果a里面存储的是基本类型,那么语句b=a就是把a的值赋值一份给b。如果a里面存储的是引用类型,那么b将指向a现在指向的位置,a的值不会赋值一份,a、b指向同一个地方。
数组的常用使用方法
数组的头尾操作
-
push()往数组的某位添加一个或多个元素
var a = [11,22,33,44]; a.push(55,66,77); console.log(a); -
pop()删除数组的最后一项,一次只能删除一项,无法删除多项,并且能够返回被删除的项
var a = [11,22,33,44]; var b = a.pop();//这样就能删除数组的最后一项,并赋值给b console.log(a);//输出删除后的a console.log(b);//输出被删除的 -
unshift()在数组开头添加一个或多个元素,并且能返回值;
var a = [11,22,33,44]; var b = a.unshift(99,88);//这样就可以往a数组开头加两个数字 console.log(a); console.log(b);//会输出11
数组的合并与拆分
-
concat()把使用它的数组和括号里的数组合并返回
var a = [11,22,33,44],b = [55,66,77]; console.log(a,b); a = a.concat(b);//把b的内容和a的内容相加赋值给a console.log(a);concat()的参数非常灵活,可以是数组变量、数组字面量、散的值也行:
var arr1 = ["东","西","南","北"]; var arr2 = ["一条","二条"]; arr1 = arr1.concat(arr2,["一筒","八条"],"幺鸡"); console.log(arr1); -
slice(起始下标,结束下标),截取起始下标到结束下标中间的内容,包括起始下标不包括结束下标,并返回新值,原值不变
var a = [11,22,33,44,55,66,77,88]; var b = a.slice(3,5); console.log(b);//返回结果是33,44如果只写开头
var a = [11,22,33,44,55,66,77,88]; var b = a.slice(3); console.log(b);//结果会从下标为3的地方截取到最后结果为倒数
倒数时,下标从-1开始
var a = [11,22,33,44,55,66,77,88]; var b = a.slice(-6,-4); console.log(b); //从倒数第4,截取到倒数第2,不包括倒数第2 -
spice——插入,删除,替换
//用于替换 var arr = [a,b,c,d,e]; arr.splice(3,2,"zh","he","ya");//(括号里前两项写从下标为几的开始替换,第二个写替换几位,可以替换也可以替换增加) console.log(arr); //用于删除 var arr = [a,b,c,d,e]; arr.splice(2);//只写了一个下标,这样数组就会从下标,往后全部删掉 console.log(arr); //用于插入 var arr = ["a","b","c","d","e"]; arr.splice(2,0,"zhanghe"); console.log(arr); -
reverse——数组倒置
var arr = [1,2,3,4,5,6]; arr.reverse; console.log(arr); -
sort——数组排序
arr.sort(function(a,b){ //如果a要放在b前面,那么返回负数 //如果a要放在b后面,那么返回正数 //如果a和b不区分大小,那么返回0 if(a < b){ return -1; }else if(a > b){ return 1; }else if(a == b){ return 0; } });//数组排序 var arr = []; var a; while (a = parseFloat(prompt())) { arr.unshift(a); } arr.sort(function(a,b){ if (a>b) { return 1; } else if(b>a) { return -1; } else { return 0; } }); alert(arr); -
join——转为字符串
//join语法 var 变量 = join(分隔符);var arr = [1,2,3,4,5]; arr = arr.join("-"); alert(arr); //1-2-3-4-5
字符串的常用使用方法
-
length测试字符串的长度
var a = "张贺"; var b = a.length; console.log(b);//输出2 -
charAt() 返回在指定位置的字符
var a = "张贺"; var b = a.charAt(0); console.log(b);//输出张,和数组的下标类似 -
concat() 连接字符串
var a = "张",b = "贺"; a = a.concat(b); console.log(a); -
indexOf() 检索字符串
console.log("我爱你i love you".indexOf("爱")); //输出1,输出前面字符串中的下标数字 -
replace() 替换
"abcdefgaa".replace("a","0"); // "0bcdefgaa" //把字符串中的a替换成了0,只替换了这一个 -
slice() 提取
"我爱你亲爱的祖国的人民币".slice(-3,-1) //"人民" -
split() 把字符串→数组, 从什么地方拆分, 就是参数
"我爱你亲爱的祖国的人民币".split("的"); //输出——["我爱你亲爱", "祖国", "人民币"],遇到的就拆分了 -
substr() 截取子串
"abcdefghijklmn".substr(3,5); //从下标为3的地方开始,取5个字符 //defgh -
substring() 截取子串,substr和substring不一样:
"我爱你亲爱的祖国的人民币".substring(6,8) //输出祖国,从下标为6的地方截取到下标为8的地方,不包括8 -
toLowerCase()、toUpperCase();
转换为大小写
"zhanghe".toUpperCase(); //"ZHANGHE"转换为大写 "ZHANGHE".toLowerCase() //"zhanghe"转换为小写

浙公网安备 33010602011771号