JavaScript闭包和范围实例详解

本文实例分析了JavaScript闭包和范围。分享给大家供大家参考,具体如下:

1.

rush:js;"> if (!("a" in window)) { var a = 1; } alert(a);

【分析】代码含义:如果window不包含属性a,就声明一个变量a并赋值为1

①JS引擎会先扫描所有的变量声明

②所有的全局变量都是window的属性

③变量声明和赋值一起用时,Js引擎会自动将它分成两部分:变量声明提前,变量赋值没有(不将赋值提前是因为他有可能影响代码执行出不可预期的结果)

所以代码执行顺序等价于

rush:js;"> var a; if(!("a" in window)) { a = 1; } alert(a);

解析:声明变量a,判断a是否存在,不存在就赋值为1,而这里a永远在window里存在,赋值语句永不执行,所以结果是undefined

2.

rush:js;"> if (!("a" in window)) { function a() { window.a = 1; } } alert(a);

【分析】

函数声明也会提前并且会覆盖变量声明,但不会覆盖变量赋值,如下例子

rush:js;"> function value(){ return 1; } var value; alert(typeof value); //"function"

rush:js;">
function value(){
  return 1;
}
var value = 1;
alert(typeof value);  //"number"

②所有全局变量都是window属性,语句var a=1;等同于window.a=1;

所以代码执行顺序等价于

rush:js;"> function a() {window.a = 1;} if(!("a" in window)) { function a() { var a = 1; } } alert(a);

输出结果:function a() {window.a = 1; }

变形:

rush:js;"> if ("a" in window) { function a() { window.a = 1; } } alert(a);

输出结果:a is not defined

函数声明里的变量定义,要到执行函数时才会定义,并不会在预编译阶段就声明变量

3.

rush:js;"> if (!("a" in window)) { var a = function () { window.a = 1; } } alert(a);

【分析】

函数声明和函数表达式区别

函数声明:

rush:js;"> function functionName(arg1,arg2){ //函数体 }

函数表达式(相当于变量赋值):

rush:js;"> var functionName = function(arg1,arg2){ //函数体 };

所以代码执行顺序等价于

rush:js;"> var a; if (!("a" in window)) { a = function () { window.a = 1; } } alert(a);

结果和第一题一样,undefined

4.

rush:js;"> var a = 1,b = function a(x) { x && a(--x); }; alert(a);

【分析】

①进入执行上下文的阶段

rush:js;"> VO(global) = { a: undefined,b: undefined }

这阶段的顺序:函数的形参->函数声明->变量声明

②执行代码阶段

rush:js;"> VO(global) = { x: undefined,a: 1 }

③定义变量b,赋值名字为a的函数(这个a只能在函数体内使用)

④如果x是任何true值(这这里应该是非0)则执行后面的语句

⑤换成更能理解的代码

rush:js;"> var a = 1,b = function(x) { x && b(--x); }; alert(a);

结果为1

5.

rush:js;"> function b(x,y,a) { arguments[2] = 10; alert(a); } b(1,2,3);

【分析】没有难点,输出10,如果改成

rush:js;"> function b(x,2);

输出undefined,因为没有传递a的值

6.

rush:js;"> function a() { alert(this); } a.call(null);

【分析】

①a.call(b)表示a对象的方法应用到b对象上(即b对象继承了a对象),根据规定,第一个参数是null或undefined,call方法就把全局对象(也就是window)作为this的值

②call()和apply()的区别:功能一样,第二个参数形式不一样,call传递多个参数,任意形式,apply第二个参数必须是数组形式,如

a.call(b,3); ==> a.apply(b,[2,3]);

输出结果:[object Window]

更多关于JavaScript相关内容可查看本站专题:《》、《》、《》、《》、《》、《》、《》及《

希望本文所述对大家JavaScript程序设计有所帮助。

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...