数组创建方式
数组是一种引用数据类型,属于对象
1.使用Array构造函数
(1)创建一个空数组var arr1 = new Array();
(2)创建一个长度规定的数组
var arr1 = new Array(20); //长度为20
(3)初始化数组
var arr1 = new Array('你', '我', '他');//输出为你,我,他
var arr2 = new Array(1, 2, 3);
2.使用数组字面量
(1)创建一个空数组var arr1=[];
(2)创建一个长度规定的数组
var arr1=[];
arr1.length = 20; //数组长度为20
(3)初始化数组
var arr1=[1,5,6];//输出为1,5,6
3.数组的下标从0开始
4.数组长度
var arr1=[1,5,6];
len = arr1.length; //输出为3
arr1.length = 2; //修改数组长度,此时数组变为 1,5
//把数组中为0的去掉
var arr1=[0,1,0,2,0,3];
var arr2=[], i;
for(i = 0; i < arr1.length; i ++){
if(arr1 [i]!==0){
arr2[arr2.length ] = arr1[i];
}
}
document.write(arr2);
函数
1.函数的定义
(1)函数也是一个对象
(2)函数是一个可以重复执行的代码块
(3)函数是完成特定功能的代码
(4)使用typeof检查一个函数时,会返回function
function getsum() { //function 函数名(){}
var sum = 0;
for (var i = 0 ; i <= 100; i ++){
sum = sum + i;
}
document.write(sum);
}
getsum(); //调用函数
2.函数的创建
(1)函数直接声明
function getsum(n) { //必须要有函数名
var sum = 0;
for (var i = 0 ; i <= n; i ++){
sum = sum + i;
}
document.write(sum);
}
getsum(100);
(2)函数表达式声明
var sum = function (a, b) {
//可以没有函数名,function后面的才是函数名,这里的sum是用来接收函数的
document.write(a+b);
};
sum(2,5);
(3)使用Function构造函数(不常用,不推荐)
var fun1 = new Function("document.write('我是函数' + '<br>');document.write('我是函数')");
fun1();
(4)函数直接声明和函数表达式声明的区别
((a))函数直接声明必须有函数名,函数表达式声明的函数名可以省略
((b))js解析器会首先会把当前作用域的函数直接声明提前到整个作用域的最前面,并不运行,只是先编译,所以不管在什么地方写函数声明,可以在任何位置调用这个函数
正确
sum(2,5);
function sum(a, b) {
document.write(a+b);
}
错误
sum(2,5);
var sum = function (a, b) {
document.write(a + b);
};
//只能在函数表达式声明的后面调用它
3.函数的参数
设置参数:是为了增强函数的功能性和函数的可拓展性,便于交互
(1)形参
形式上参与运算的变量,无实际值,为实参占位置,就像一个躯壳一样
如function sum(a,b){}
中的a,b
,函数内部的值时赋值实参的值,无法改变外部(实参)的值
(2)实参
真是参与运算的变量,如sum(3,5);
中的3,5
就是实参
(3)在js中,实参和形参的个数可以不一致
少传不运算,输出为NaN;多传,多的实参不参与运算
4.arguments对象
伪数组对象
(1)arguments对象仅仅属于函数
在函数里输出arguments
出现:
Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 1 //传进函数的实参
1: 2 //传进函数的实参
callee: ƒ (a, b) //指向Arguments的函数
length: 2 //实参的个数
Symbol(Symbol.iterator): ƒ values()
__proto__: Object
(2)求函数的实参和形参个数
实参个数arguments.length
形参个数sum.length
function sum(a, b) {
//函数的实参
document.write(arguments.length + '<br>');
document.write(sum.length); //函数的形参
}
sum(1,2,3,4);
(3)输出完整的函数arguments.callee
function sum(a, b) {
document.write(arguments.callee);
}
(4)求很多数的和
arguments
可以当做数组进行遍历
//第1种
function getsum(arr) {
var sum = 0;
for (var i = 0 ; i < arr.length; i ++){
sum = sum + arr[i];
}
document.write(sum + '<br>');
}
getsum([20,56,39]);
//第2种
function getsum1(arr) {
var sum = 0;
for (var i = 0 ; i < arguments.length; i ++){
sum = sum + arguments[i];
}
document.write(sum);
}
getsum1(20,56,40);
5.return的运用
(1)当一个函数被调用,通常会从函数的开始执行到结束,如果想提前结束该函数的执行可以使用return语句,return语句后面的语句永远将不会执行。
(2)如果函数没有使用return语句,或者使用了return但是return后面没有任何语句,那么函数的返回值是:undefined
(3)所以推荐的做法是:要么让函数始终都返回一个值,要么不要有返回值
注意函数有无形参都既可以直接输出,也可以用return返回。
6.匿名函数
匿名函数:没有命名的函数
作用
(1)用在绑定事件的时候
document.onclick = function () {
alert(1);
}
(2)定时器
setInterval(function () {
document.write('每秒爱你一遍');
},1000) //每隔多久做一次,单位是毫秒,1000就是1s
(3)立即执行函数(闭包)
(function (a, b) {
document.write(a+b); //输出为3
})(1,2)
7.回调函数
(1)回调函数就是一个通过函数调用的函数
(2)如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,这就是回调函数
function add(a, b) {
return a+b;
}
function sub(a, b) {
return a-b;
}
function cal(a, b, func) {
return func(a,b);
}
var rusult1 = cal(10,20,add), result2 = cal (20,10,sub);
document.write(rusult1 + '<br>');
document.write(result2);
(3)常用于递归
8.变量的作用域
(1)作用域:变量可以起作用的一个范围
(2)全局变量:在任何地方都可以访问的变量;对应全局作用域;全局变量只有关闭网页或者浏览器才会被销毁
(3)局部变量:只有在固定的代码片段里可访问的变量,最常见的是在函数内部定义的变量;对应局部作用域;局部变量退出局部作用域后就会被销毁
注意不使用var
定义的变量,在哪里都是全局变量
function f() {
str1 = "hahahha";
document.write(str1 + '<br>');
}
f();
document.write(str1);
//str没有用var定义,所以是全局变量,在这里仍旧可以使用
(4)块级作用域
任何一对花括号{}中的语句都属于一个块,在这之中定义的所有变量在代码块外是不可见的,我们称之为块级作用域
注意在es5之前{}没有块级作用域,es5{}有函数作用域和全局作用域,在es6里{}都有块级作用域
(5)作用域链
1.花括号外再一层花括号再一层花括号······由很多{}
嵌套而成的
2.只要有代码,就有一层作用域,比如
<script>{}</script>
有2层作用域
3.找变量是从最内一层作用域逐层向外找,不能平级或者由外往里找
注意for循环里的i是全局变量
for (var i=0 ; i< 10 ; i++){
}
document.write(i); //i输出为10
9.预解析
(1)js代码的执行是由浏览器中的js解析器来执行的,js解析器执行代码分为两个过程:(先)预解析过程和(再)代码执行过程
(2)先将变量声明提到当前作用域的最前面(只提升声明,不提升赋值),再将函数直接声明提到当前作用域的最前面(只提升声明,不提升调用)
var num1 = 10;
function f() {
//只将 var num1 提升到最前面,并没有将赋值提到前面
document.write(num1); //所以输出为undefined
/*为什么没有输出全局变量的num1
* 是因为已经在内层找到该变量
*就不用取外层找了
*/
var num1 = 20;
}
f();
注意es5有变量提升(var命名的变量),es6中没有变量提升(let命名的变量)
function f() {
var num1 = num2 = num3 =100;
}
这里的num1是局部变量,但num2、num3是全局变量,因为num2、num3没有用var定义
10.变量提升
(1)变量提升:定义变量时,变量的声明会被提升到作用域的最前面,但变量的赋值不会
(2)函数提升:js解析器会把当前作用域的函数声明提到整个作用域的最前面