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 相关文章推荐
解决AJAX中跨域访问出现'没有权限'的错误
Aug 20 Javascript
js单例模式的两种方案
Oct 22 Javascript
Shell脚本实现Linux系统和进程资源监控
Mar 05 Javascript
Javascript实现计算个人所得税
May 10 Javascript
jQuery实现的兼容性浮动层示例
Aug 02 Javascript
Javascript 数组去重的方法(四种)详解及实例代码
Nov 24 Javascript
[原创]SyntaxHighlighter自动识别并加载脚本语言
Feb 07 Javascript
vue+node+webpack环境搭建教程
Nov 05 Javascript
vue-cli3 从搭建到优化的详细步骤
Jan 20 Javascript
详解mpvue中小程序自定义导航组件开发指南
Feb 11 Javascript
Vue自定义属性实例分析
Feb 23 Javascript
JS左右无缝轮播功能完整实例
May 16 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
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
实现PHP+Mysql无限分类的方法汇总
2015/03/02 PHP
php实现生成验证码实例分享
2016/04/10 PHP
thinkPHP实现多字段模糊匹配查询的方法
2016/12/01 PHP
Javascript new关键字的玄机 以及其它
2010/08/25 Javascript
基于jQuery中对数组进行操作的方法
2013/04/16 Javascript
javascript用户注册提示效果的简单实例
2013/08/17 Javascript
JS获取地址栏参数的几种方法小结
2014/02/28 Javascript
jQuery实现按钮的点击 全选/反选 单选框/复选框 文本框 表单验证
2015/06/25 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
微信小程序 window_x64环境搭建
2016/09/30 Javascript
微信小程序 教程之wxapp视图容器 swiper
2016/10/19 Javascript
JS中touchstart事件与click事件冲突的解决方法
2018/03/12 Javascript
vue 国际化 vue-i18n 双语言 语言包
2018/06/07 Javascript
Vue.js递归组件实现组织架构树和选人功能
2019/07/04 Javascript
Vue的编码技巧与规范使用详解
2019/08/28 Javascript
nodejs各种姿势断点调试的方法
2020/06/18 NodeJs
Vue实现多页签组件
2021/01/14 Vue.js
[01:20]辉夜杯背景故事宣传片《辉夜传说》
2015/12/25 DOTA
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
python 判断是否为正小数和正整数的实例
2017/07/23 Python
基于Python中capitalize()与title()的区别详解
2017/12/09 Python
详解Python 正则表达式模块
2018/11/05 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
python爬虫爬取监控教务系统的思路详解
2020/01/08 Python
python图片剪裁代码(图片按四个点坐标剪裁)
2020/03/10 Python
解决运行django程序出错问题 'str'object has no attribute'_meta'
2020/07/15 Python
Python 数据分析之逐块读取文本的实现
2020/12/14 Python
详解Canvas实用库Fabric.js使用手册
2019/01/07 HTML / CSS
上班玩游戏检讨书
2014/02/07 职场文书
全民创业工作总结
2015/08/13 职场文书
团结友爱主题班会
2015/08/13 职场文书
高三语文教学反思
2016/02/16 职场文书
2016年“我们的节日·清明节”活动总结
2016/04/01 职场文书
你真的了解redis为什么要提供pipeline功能
2021/06/22 Redis
Java日常练习题,每天进步一点点(38)
2021/07/26 Java/Android