JavaScript的变量声明与声明提前用法实例分析


Posted in Javascript onNovember 26, 2019

本文实例讲述了JavaScript的变量声明与声明提前用法。分享给大家供大家参考,具体如下:

JavaScript的变量声明

JavaScript的变量声明语句无论出现在何处,都会先于其他代码首先被执行。使用var关键词声明变量的作用域是当前的执行上下文,有可能是外围函数,或者,当变量声明在函数体之外时,则为全局变量。

向一个未声明变量赋值会隐式地将其创建为一个全局变量(它变成了全局对象的一个属性)。声明变量与未声明变量之间的区别为:

1. 声明变量的作用范围限定在其执行的上下文环境中。未声明的变量总是全局的。

function x() {
 y = 1;  // Throws a ReferenceError in strict mode
 var z = 2;
}
x();
console.log(y); // logs "1" 
console.log(z); // Throws a ReferenceError: z is not defined outside x

2. 声明变量在其他代码执行之前创建。未声明的变量在其赋值语句执行之前都是不存在的。

console.log(a);        // Throws a ReferenceError.
console.log('still going...'); // Never executes.
var a;
console.log(a);        // logs "undefined" or "" depending on browser.
console.log('still going...'); // logs "still going...".

3. 声明变量是执行上下文(函数或者全局)的不可配置的属性。而未声明变量是可配置的(例如,可以被delete)

var a = 1;
b = 2;
delete this.a; // Throws a TypeError in strict mode. Fails silently otherwise.
delete this.b;
console.log(a, b); // Throws a ReferenceError. 
// The 'b' property was deleted and no longer exists.

由于以上三点不同,使用未声明变量可能会带来意想不到的结果。因此建议无论是全局变量还是局部变量,在使用前都要声明。在ECMAScript5的严格模式下,对未声明变量赋值会抛出一个错误。

声明提前(var hoisting):

JavaScript的函数作用域是指在函数内声明的所有变量在函数体内是始终可见的。有趣的是,这意味着变量甚至可以先使用,后声明。

JavaScript的这一特性被非正式地称为声明提前(hoiosting),即JavaScript函数中所有变量的声明都被“提前”至函数体的顶部。

(“声明提前”的操作是在JavaScript引擎的“预编译”时进行的,即在代码运行之前)

例如下面的JavaScript代码:

var scope = "global";
function f() {
  alert(scope);
  var scope = "local"; //覆盖全局变量
  alert(scope);
}

读者可能误以为函数f的第一个alert会输出"global",因为代码此时还没有执行到var语句声明局部变量的代码行。

其实不然,由于函数作用域的特性,局部变量在整个函数体内始终是有定义的,亦即,在函数体内局部变量覆盖了同名的全局变量。尽管如此,只有程序执行到var语句时,局部变量才会被赋值。因此上述过程等价于,将函数体内的变量声明“提前”至函数体顶部,而变量的初始化保留在原处。

function f() {
  var scope; //函数体顶部声明局部变量
  alert(scope); //输出"undefined"
  scope = "local"; //变量初始化赋值
  alert(scope); //输出"local"
}

基于此原因,建议将变量的声明都放在作用域的顶部(全局代码的顶端,或者函数代码的开始),从而清楚地区分变量的作用域,哪些是函数作用域,哪些在作用域链上解析。

参考资料:

1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

2. 《JavaScript权威指南》 第6版 中文版

更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

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

Javascript 相关文章推荐
PJBlog插件 防刷新的在线播放器
Oct 25 Javascript
JsRender for index循环索引用法详解
Oct 31 Javascript
js在指定位置增加节点函数insertBefore()用法实例
Jan 12 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
Jun 08 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
Jul 27 Javascript
Websocket协议详解及简单实例代码
Dec 12 Javascript
浅谈DOM的操作以及性能优化问题-重绘重排
Jan 08 Javascript
xmlplus组件设计系列之分隔框(DividedBox)(8)
May 02 Javascript
js学习总结之DOM2兼容处理顺序问题的解决方法
Jul 27 Javascript
高性能的javascript之加载顺序与执行原理篇
Jan 14 Javascript
vue脚手架搭建项目的兼容性配置详解
Jul 17 Javascript
Vue实现商品飞入购物车效果(电商项目)
Nov 26 Javascript
vue中keep-alive,include的缓存问题
Nov 26 #Javascript
JS插件amCharts实现绘制柱形图默认显示数值功能示例
Nov 26 #Javascript
jQuery与原生JavaScript选择HTML元素集合用法对比分析
Nov 26 #jQuery
原生js实现贪食蛇小游戏的思路详解
Nov 26 #Javascript
高效jQuery选择器的5个技巧实例分析
Nov 26 #jQuery
JavaScript计算正方形面积
Nov 26 #Javascript
javaScript中indexOf用法技巧
Nov 26 #Javascript
You might like
PHP 文件上传进度条的两种实现方法的代码
2007/11/25 PHP
php使用codebase生成随机数
2014/03/25 PHP
Symfony核心类概述
2016/03/17 PHP
thinkPHP5使用Rabc实现权限管理
2019/08/28 PHP
CL vs ForZe BO5 第三场 2.13
2021/03/10 DOTA
利用jQuery的$.event.fix函数统一浏览器event事件处理
2009/12/21 Javascript
JavaScript 学习初步 入门教程
2010/03/25 Javascript
jQuery getJSON 处理json数据的代码
2010/07/26 Javascript
关于JQuery($.load)事件的用法和分析
2013/04/09 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
用js的document.write输出的广告无阻塞加载的方法
2014/06/05 Javascript
JS使用ajax从xml文件动态获取数据显示的方法
2015/03/24 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
jquery实现的伪分页效果代码
2015/10/29 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
vue实例中data使用return包裹的方法
2018/08/27 Javascript
JavaScript中var的重要性实例分析
2019/07/09 Javascript
微信小程序里引入SVG矢量图标的方法
2019/09/20 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
[01:16:37]【全国守擂赛】第三周决赛 Dark Knight vs. 一个弱队
2020/05/04 DOTA
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
python分割列表(list)的方法示例
2017/05/07 Python
解决python 自动安装缺少模块的问题
2018/10/22 Python
网易2016研发工程师编程题 奖学金(python)
2019/06/19 Python
Python进度条的制作代码实例
2019/08/31 Python
python对象转字典的两种实现方式示例
2019/11/07 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
什么情况下你必须要把一个类定义为abstract的
2013/01/06 面试题
Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
2015/01/27 面试题
大专学生求职自荐信
2014/07/06 职场文书
三人合伙协议书范本
2014/10/29 职场文书
教师节表彰会主持词
2015/07/06 职场文书
早恋主题班会
2015/08/14 职场文书
MySQL修炼之联结与集合浅析
2021/10/05 MySQL
MySQL一劳永逸永久支持输入中文的方法实例
2022/08/05 MySQL