本文实例讲述了JavaScript变量声明提升。分享给大家供大家参考,具体如下:
如下代码输出的结果是?
var num = 123; function foo1(){ console.log( num ); //undefined var num = 456; console.log( num ); //456 } foo1();
Javascript代码执行分为两个大步:
预解析的过程
代码的执行过程
1.预解析与变量声明提升
程序在执行过程中,会先将代码读取到内存中检查,会将所有的声明在此进行标记,所谓的标记就是让JS解析器知道有这个名字,后面在使用名字的时候不会出现未定义的错误。这个标记过程就是提升。
声明:
名字的声明,标识符声明(变量名声明)
- 名字的声明就是让解析器知道有这个名字
- 名字没有任何数据与之对应
函数的声明
- 函数声明包含两部分
-
函数声明与函数表达式有区别,函数声明是单独写在一个结构中,不存在任何语句,逻辑判断等结构中
function f() {} function func() { // 函数声明 } if ( true ) { function func2 () {} //函数表达式 } var f = function func3 () {}; //函数表达式 this.sayHello = function () {}; //函数表达式 var i= 1; function func4 () {} // 函数声明 var j = 2; }
首先函数声明告诉解析器有这个名字存在,该阶段与名字声明一样
告诉解析器,这个名字对应的函数体是什么
var num = 1; function num () { alert( num ); } num(); // 报错
分析
-
预解析代码,提示名字
- 首先提升名字num
- 再提升函数名,但是名字已经存在,因此只做第二部,让名字与函数体对应上
- 结论就是 代码中已经有一个函数 num 了
-
开始执行代码,第一句话从赋值语句开始执行
- 给num赋值为1
- 覆盖了函数
- 调用num,由于num中存储的是数组1,因此报错
2.代码分析举例
程序1
var num = 123; function foo1(){ console.log( num ); //undefined var num = 456; console.log( num ); //456 } foo1();
- 预解析,提升 num 名字和 foo1 函数
- 执行第一句话:
num = 123;
-
执行函数调用
- 函数调用进入函数的一瞬间也要进行预解析,此时解析的是变量名 num
- 在函数内部是一个独立的空间,允许使用外部的数据,但是现在 num 声明同名,即覆盖外面的
- 执行第一句 打印num,没有数据,undefined
- 执行第二句 赋值:num = 456;
- 执行第三句 打印num,结果456
程序2
if ( ! 'a' in window ) { var a = 123; } console.log( a );
首先,预解析,读取提升 a
,有一个名字 a
存在了
其次,in
运算符:判断某一个字符串描述的属性名是否在对象中
- var o = { name:'jim' }; 'name' in o,'age' in o
-
执行第一个判断:! 'a' in window
- 'a' in window 结果为真
- !得到假
- if内部的赋值不进行
最后,打印结果 a
的值为 undefined
程序3
if ( false ) { function f1 () { console.log( 'true' ); } } else { function f1 () { console.log( 'false' ); } } f1();
预解析:提升 f1 函数,只保留提升后的内容,所以打印是 false
执行代码,第一句话就是一个空的if结构
if ( true ) { } else { }
执行函数调用,得到 false
3.问题
function foo () } {} var foo = function () {};
上面的语法是声明,可以提升,因此在函数上方也可以调用
下面的语法是函数表达式,函数名就是foo ,他会提升,提升的不是函数体
函数表达式也是支持名字语法
var foo = function func1 () {}; func();
函数有一个属性name,表示的是函数名,只有带有名字的函数定义,才会有name属性值,否则是“”
- 但是,函数表达式的名字,只允许在函数内部使用,IE8可以访问
- ()可以将数据转化为表达式
新的浏览器中,写在if、while、do..while结构中的函数,都会将函数的声明转换成特殊的函数表达式
将代码
if (...) { function foo () { ... } }
转换成
if (...) { var foo = function foo () { .... } }
完。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]