20150203+JS巩固与加强1-02

四、JavaScript中的作用域链

例1:全局作用域与局部作用域

clip_image002

说明:我们所说的全局变量与和局部变量其实只是相对的

clip_image004

例2:全局作用域中可以不可以直接访问局部变量

clip_image006

答:以上情况是不允许的,原因:

1)由于作用域链不允许

2)由于JavaScript的垃圾回收机制

例3:探讨函数与函数的关系

clip_image008

通过观察,发现以上代码可以正常执行

例2:函数如果在函数中,那么也存在作用域关系,如下图所示

clip_image010

通过运行以上代码,系统会提示fn1()缺少对象,主要是由于当执行第15行后,系统会自动回收display函数所占用的内存空间,会导致调用fn1函数无法找到,所以会产生缺少对象错误。

回顾php代码,在函数内部定义函数,那么在函数外部是否可以访问呢?

例3:

clip_image012

通过运行以上代码,返回结果displayfn1

也就是说明我们在PHP中可以调用函数中的函数

1、深入探讨JavaScript与PHP中的作用域问题

PHP中的作用域问题:

clip_image014

clip_image016

在PHP代码运行过程中,系统首先会加载display函数,并在运行栈区中开辟一段连续的内存空间,当display函数被调用时,系统会自动在运行栈区中,开辟一段独立且平行的内存空间用于fn1的存储,由于两者处于平行独立关系,所以我可以在display调用完成后,直接调用fn1函数。

JS作用域

clip_image018

clip_image020

在JavaScript代码运行过程中,系统首先会加载display函数,并在运行栈区中开辟一段连续的内存空间,当display函数执行时,系统会自动在display函数作用域范围内继续开辟一段连续的内存空间用于保存fn1函数,由于两者处于包含关系,我们我们没办法直接在函数外直接调用fn1函数

例4:

clip_image022

通过观察以上代码,我们会发现,系统弹出100,原因:

2、作用域链

当我们在函数内部调用某一变量时,系统首先在当前函数中寻找var声明语句(var i),如找到则直接使用,否则继续向上一级作用域寻找,如找到,则直接使用,否则继续向上寻找,直到全局作用域,如找到,则使用,否则会在全局作用域中声明该变量,我们把这个过程就称之为作用域链

作用域链和原理图:

clip_image024

例5:

clip_image026

以上代码弹出结果为1000,原理同上。

例6:

clip_image028

运行结果:1000,1000

五、script代码段

1、JavaScript中script代码段执行流程:

1、读入第一个代码段

2、编译

声明变量,声明函数,语法检查,语义检查,代码优化,分析并得到代码树

3、执行

代码调用,代码执行

var i = 100;

编译过程:var i = undefined;

执行过程:i=100;

4、读入下一个代码段

5、编译

6、执行

7、……

8、结束

2、探讨代码段错误(编译错误、执行错误)的影响

例1:编译错误对当前代码段所产生的影响

clip_image030

通过运行发现,代码无法执行。原因:

我们知道代码执行分为两个阶段:

编译阶段与执行阶段,我们没有写圆括号,那么系统在编译过程就会产生错误,所以后面的代码与前面的代码都无法正常执行。

说明:编译错误会导致当前代码段无法执行

例2:执行错误对当前代码段的影响

clip_image032

运行结果:hello,报错

说明:当前代码在编译阶段没有任何异常,在运行时,首先运行第9行代码,运行到第10行时,系统找不到display函数,所以会报错(执行错误),会导致后面的word无法输出,所以可以说明:

script代码段执行错误只对当前代码后面的代码有影响,而不会影响前面代码的执行

例3:编译错误对后面代码段的影响

clip_image034

例4:执行错误对后面代码段的影响

clip_image036

通过例3与例4案例,我们可以得出以下结论,无论编译错误还是执行错误,都只对当前代码段有影响,而不会对后面的代码产生影响。

3、script代码段执行原理图:

clip_image038

面试题:判断当前程序的执行结果?

clip_image040

执行结果:

undefined,1000

说明:当函数执行到第9-10行时,系统定义全局变量i=100与声明函数,当执行到第15行,系统调用display函数,由于第11行代码执行alert(i),由于作用域链原则,系统首先会在当前作用域中寻找var声明,在第12行找到了var声明,又由于代码执行分为两个阶段编译与执行:由于函数display内在编译时会定义var i=undefined所以当执行第11行代码时,系统首先输出undefined,当执行到12行时,系统自动为变量赋值i=1000,当执行到13行时,系统自动弹出刚才已赋值的变量i=1000,所以两次结果为undefined与1000。

六、JavaScript中的数组

1、什么是数组?

答:一组数据的集合

一维数组

二维数组

多维数组

2、数组的定义

l var arr=[值1,值2,值3]; //隐式创建

l var arr=new Array(值1,值2,值3); //显示创建或直接实例化

l var array=new Array(size); //显示创建并指定数组长度

例1:通过以上三种方式创建数组

clip_image042

例2:如何对已定义数组进行引用

基本语法:

数组名称[索引]

clip_image044

例3:如何遍历输出数组数据

1)通过for循环进行遍历输出

数组拥有一个属性length,标识数组长度

clip_image046

运行结果:

clip_image048

2)通过for…in…进行遍历输出

clip_image050

输出结果:

clip_image051

例4:二维数组定义

clip_image053

运行结果:

clip_image055

例5:二维数组遍历

clip_image057

运行结果:

clip_image059

3、定义文本下标数组

例6:文本下标数组

clip_image061

运行结果:

弹出小美

例7:文本下标数组元素是不计入数组长度的

clip_image063

输出结果:当前数组中共有3个元素

IE调试工具,F12弹出,如下图

clip_image065

调试结果如下:

clip_image067

在数组中,我们的文本下标都是通过属性的形式追加到数组中,所以其不计入数组长度。

例8:遍历输出带文本下标型数组

示例代码:

clip_image069

运行结果:

clip_image071

七:作业

作业一:JavaScript中与Array数组相关的系统函数

添加数组元素:

l arrayObject.push(newelement1,newelement2,....,newelementX)

l arrayObject.unshift(newelement1,newelement2,....,newelementX)

l arrayObject.splice(index,howmany,element1,.....,elementX)

删除数组元素:

l arrayObject.pop()

l arrayObject.shift()

l arrayObject.splice(index,howmany)

数组的截取与合并:

l arrayObject.slice(start[,end])

l arrayObject.concat(arrayX,arrayX,......,arrayX)

l 返回新数组

数组的连接:

l arrayObject.join(separator)

数组的切割:

l stringObject.split(separator, howmany)

作业二:省市级联(二级联动)

北京 (海淀区,朝阳区)

广州 (天河,海珠区)

原文地址:https://www.cnblogs.com/lifushan/p/5423319.html