目录
一、arguments(伪数组,并不是真正意义上的数组)
1、特性
2、arguments 内置对象的优缺点
二、一些arguments的运用
1、利用函数求任意个数的最大值
2、函数之间的相互调用
三、声明函数的方法
1. 利用函数关键字自定义函数(命名函数)
2. 函数表达式(匿名函数)
3、一些声明函数的事项
四、JavaScript的作用域
1、全局作用域:
2、局部作用域(函数作用域):
3、代码解析:
一、arguments(伪数组,并不是真正意义上的数组)
arguments的使用,只有函数才有 arguments 对象,而且是每个函数都内置好了这个arguments。
1、特性
1. 具有数组的 length 属性
2. 按照索引的方式进行存储的
3. 它没有真正数组的一些方法 pop() push() sort() 等等
2、arguments 内置对象的优缺点
优点:不需要形参
缺点:不能使用数组api
二、一些arguments的运用
1、利用函数求任意个数的最大值
function max() {var max = arguments[0]for (var i = 1; i < arguments.length; i++) {if (max < arguments[i]) max = arguments[i]}console.log(max);}
2、函数之间的相互调用
function a() {console.log(1);b()}function b() {console.log(2);}
三、声明函数的方法
1. 利用函数关键字自定义函数(命名函数)
function fn() {console.log(this);}fn()
2. 函数表达式(匿名函数)
var fn2 = function (a) {console.log(this);}fn2('a')
3、一些声明函数的事项
(1)函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
(2)函数表达式也可以进行传递参数
(3)函数中的this指向 ,谁调用它它就指谁(匿名,命名函数this指向window)
四、JavaScript的作用域
代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突,js的作用域分为全局作用域和局部作用域。
1、全局作用域:
整个script标签 或者是一个单独的js文件,可以在任何地方调用或使用
2、局部作用域(函数作用域):
在函数内部就是局部作用域,这个变量的名字只在函数内部起效果和作用
3、代码解析:
在下列代码中,a为全局作用域,在整个js文件下进行使用,而b为局部作用域,只能在函数 fn()中进行使用
var a = 5function fn() {console.log(a);var b = 10console.log(b);}fn()
五、变量的作用域
根据作用域的不同,变量也可以分为全局变量和局部变量
1. 全局变量: 在全局作用域下的变量 在全局下都可以使用
注意:在函数内部没有声明直接赋值的变量也属于全局变量
2. 局部变量:在局部作用域下的变量,或者在函数内部的变量
注意: 函数的形参也可以看做是局部变量
var a = 6;// var b;function fn(x,y){//var x,yconsole.log(a);var b = 7console.log(b);}fn()console.log(b);//在上述代码中,先声明一个全局变量 a = 6//然后定义一个函数,并赋予其形参一个局部变量//在函数内部声明了一个局部变量 b = 7
3. 从执行效率来看全局变量和局部变量
(1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
(2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源
块级作用域
js的作用域为全局作用域和局部作用域 ,现阶段js 没有块级作用域,而在 es6 的时候新增了块级作用域
在使用大括号( {} )、if {} 、for {} 时,使用的就是块级作用域
在es6中let,const 都可以声明一个块级作用域,而var可以声明全局变量,let const不行
if (3 < 5) {var num = 10 }// 外面的是不能调用num的console.log(num);
六、作用域链
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链,其遵循就近原则。
代码解析:
在下列代码的运行中,先声明了三个变量并进行赋值,然后定义一个函数 fn,其中在控制台打印a的值。此时a的值为全局变量 a =10 进行取用。
随后定义一个函数 fn1,其中重新对a进行赋值,此时的a遵循就近原则调用的是 a =20的值。
在fn1中打印变量 b 的值,但是由于在局部 fn1 中没有对其进行声明赋值,所以遵循就近原则后取全局变量 b =30 的值。
(在fn 中声明的b=20属于局部变量,只能在fn函数中进行使用,在进行调用时无法取用)
var num = 1; //全局变量var a = 10;var b = 30;function fn() {console.log(a); //a = 10var b = 20;fn1()}function fn1() {var a = 20;console.log(a);//a = 20console.log(b);//b = 30}fn()
一些案例:
var num = 456; //全局的变量function f1() {var num = 123; //局部变量f2();}function f2() {// var num = 0; //局部变量 就近原则console.log(num); // 站在目标出发,一层一层的往外查找}//该处代码num的值为全局变量456
需注意定义与调用的区别:
定义一个在其他函数内部的函数时,需注意函数内局部变量的影响,即我们需要向外一层一层的查找。
而在调用函数时,我们需注意使用变量的是声明函数的位置,而非调用函数的位置,即从函数声明的位置出发去查找
var a = 1; //全局的变量var b = 5function fn1() {var a = 2;var b = '22';fn2();function fn2() {var a = 3;fn3();function fn3() {var a = 4;console.log(a);//4console.log(b);//"22"}}}fn1();
在对这些作用域链的了解中,只需进行初步了解原理和使用即可,在完整的项目中不会进行多层嵌套的情况出现。
七、预解析
1、在运行js文件时,我们先进行预解析后才执行代码
(1). 预解析时js引擎会把js里面所有的 var 还有 function 申明,提升到当前作用域的最前面
(2). 代码执行时按照代码书写的顺序从上往下执行
2、预解析分为 变量预解析(变量申明提升) 和 函数预解析(函数提升)
(1) 变量提升:把所有的变量声明提升到当前的作用域最前面 ,不提升赋值操作
(2) 函数提升:把所有的函数声明提升到当前作用域的最前面 ,不调用函数
需注意预解析和作用域链的搭配使用会导致原有的一些代码赋值和声明的改变,我们