在javascript中, 理解变量的作用域以及变量提升是非常有必要的。这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解。

变量作用域
“一个变量的作用域表示这个变量存在的上下文。它指定了你可以访问哪些变量以及你是否有权限访问某个变量。”
变量作用域分为局部作用域和全局作用域。
局部变量(处于函数级别的作用域)
不像其他对面对象的编程语言(比方说C++,Java等等),javascript没有块级作用域(被花括号包围的);当是,javascript有拥有函数级别的作用域,也就是说,在一个函数内定义的变量只能在函数内部访问或者这个函数内部的函数访问(闭包除外,这个我们过几天再写个专题)。
函数级别作用域的一个例子:
var name = "Richard";
function showName () {
var name = "Jack"; // local variable; only accessible in this showName function
console.log (name); // Jack
}
console.log (name); // Richard: the global variable
没有块级作用域:
var name = "Richard";
// the blocks in this if statement do not create a local context for the name variable
if (name) {
name = "Jack"; // this name is the global name variable and it is being changed to "Jack" here
console.log (name); // Jack: still the global variable
}
// Here, the name variable is the same global name variable, but it was changed in the if statement
console.log (name); // Jack
不要忘记使用var关键字
如果声明一个变量的时候没有使用var关键字,那么这个变量将是一个全局变量!
// If you don't declare your local variables with the var keyword, they are part of the global scope
var name = "Michael Jackson";
function showCelebrityName () {
console.log (name);
}
function showOrdinaryPersonName () {    
name = "Johnny Evers";
console.log (name);
}
showCelebrityName (); // Michael Jackson
// name is not a local variable, it simply changes the global name variable
showOrdinaryPersonName (); // Johnny Evers
// The global variable is now Johnny Evers, not the celebrity name anymore
showCelebrityName (); // Johnny Evers
// The solution is to declare your local variable with the var keyword
function showOrdinaryPersonName () {    
var name = "Johnny Evers"; // Now name is always a local variable and it will not overwrite the global variable
console.log (name);
}
局部变量优先级大于全局变量
如果在全局作用域中什么的变量在局部作用域中再次声明,那么在局部作用域中调用这个变量时,优先调用局部作用域中声明的变量:
var name = "Paul";
function users () {
// Here, the name variable is local and it takes precedence over the same name variable in the global scope
var name = "Jack";
// The search for name starts right here inside the function before it attempts to look outside the function in the global scope
console.log (name); 
}
users (); // Jack
全局变量
所有在函数外面声明的变量都处于全局作用域中。在浏览器环境中,这个全局作用域就是我们的Window对象(或者整个HTML文档)。
每一个在函数外部声明或者定义的变量都是一个全局对象,所以这个变量可以在任何地方被使用,例如:
// name and sex is not in any function
var myName = "zhou";
var sex = "male";
//他们都处在window对象中
console.log(window.myName); //paul
console.log('sex' in window); //true
如果一个变量第一次初始化/声明的时候没有使用var关键字,那么他自动加入到全局作用域中。
function showAge(){
//age初始化时没有使用var关键字,所以它是一个全局变量
age = 20;
console.log(age);
}
showAge();  //20
console.log(age); //因为age是全局变量,所以这里输出的也是20
setTimeout中的函数是在全局作用域中执行的
setTimeout中的函数所处在于全局作用域中,所以函数中使用this关键字时,这个this关键字指向的是全局对象(Window):
var Value1 = 200;
var Value2 = 20;
var myObj = {
Value1 : 10,
Value2 : 1,
caleculatedIt: function(){
setTimeout(function(){
console.log(this.Value1 * this.Value2);
}, 1000);
}
}
myObj.caleculatedIt(); //4000
为了避免对全局作用域的污染, 所以一般情况下我们尽可能少的声明全局变量。 
变量提升(Variable Hoisting)
所以的变量声明都会提升到函数的开头(如果这个变量在这个函数里面)或者全局作用域的开头(如果这个变量是一个全局变量)。我们来看一个例子:
function showName () {
console.log ("First Name: " + name);
var name = "Ford";
console.log ("Last Name: " + name);
}
showName (); 
// First Name: undefined
// Last Name: Ford
// The reason undefined prints first is because the local variable name was hoisted to the top of the function
// Which means it is this local variable that get calls the first time.
// This is how the code is actually processed by the JavaScript engine:
function showName () {
var name; // name is hoisted (note that is undefined at this point, since the assignment happens below)
console.log ("First Name: " + name); // First Name: undefined
name = "Ford"; // name is assigned a value
// now name is Ford
console.log ("Last Name: " + name); // Last Name: Ford
}
函数声明会覆盖变量声明
如果存在函数声明和变量声明(注意:仅仅是声明,还没有被赋值),而且变量名跟函数名是相同的,那么,它们都会被提示到外部作用域的开头,但是,函数的优先级更高,所以变量的值会被函数覆盖掉。
// Both the variable and the function are named myName
var myName;

function myName () {
console.log ("Rich");
}
// The function declaration overrides the variable name
console.log(typeof myName); // function
但是,如果这个变量或者函数其中是赋值了的,那么另外一个将无法覆盖它:
// But in this example, the variable assignment overrides the function declaration
var myName = "Richard"; // This is the variable assignment (initialization) that overrides the function declaration.
function myName () {
console.log ("Rich");
}
console.log(typeof myName); // string
最后一点, 在严格模式下,如果没有先声明变量就给变量赋值将会报错!

http://www.2cto.com/kf/201310/253457.html

转载于:https://www.cnblogs.com/qiangupc/p/4224221.html

js变量作用域和变量提升相关推荐

  1. Tensorflow变量作用域及变量初始化

    本文主要讲述Tensorflow中的变量作用域及变量初始化.先来区分几个概念: tf.name_scope():为了更好地管理变量的命名空间而提出的.比如在 tensorboard 中,因为引入了 n ...

  2. linux shell变量作用域,Shell变量的作用域:Shell全局变量、环境变量和局部变量

    Shell变量的作用域(Scope),就是Shell变量的有效范围(可以使用的范围). 在不同的作用域中,同名的变量不会相互干涉,就好像A班有个叫小明的同学,B班也有个叫小明的同学,虽然他们都叫小明( ...

  3. js的变量作用域 ,变量提升

    (function(){a = 5;alert(window.a);var a = 10;alert(a); })(); 结果: undefined 10 代码等同于下面 var a = undefi ...

  4. python变量作用域 for_python变量作用域

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  5. Python之变量作用域

    文章目录 一 变量作用域 1. Local(局部变量) 2. Enclosed(嵌套) 3. Global(全局) 4. Built-in(内置) 二 变量使用规则 三 变量的修改 1. global ...

  6. JS 作用域与变量提升---JS 学习笔记(三)

    你知道下面的JavaScript代码执行时会输出什么吗? var foo = 1; function bar() {if (!foo) {var foo = 10;}console.log(foo); ...

  7. uniapp 获取到js文件var一个变量怎么获取到这个变量值_浅析Js中const,let,var的区别及作用域...

    理解:let变量的作用域只能在当前函数中 js中const,let,var的区别及作用域_lianzhang861的博客-CSDN博客​blog.csdn.net 全局作用域中,用 const 和 l ...

  8. js高级第一章--变量提升,函数提升

    js高级第一章–变量提升,函数提升 文章目录 前言 一.什么是js里的提升? 二.js变量提升 三.js函数提升 四.特殊情况 总结 前言 在js中,最基本的声明方式有三种,即:var,let,con ...

  9. JavaScript 作用域、变量提升

    JavaScript 作用域 JavaScript 作用域 JavaScript 局部作用域 JavaScript 全局变量 JavaScript 变量生命周期 函数参数 HTML 中的全局变量 ES ...

最新文章

  1. ModuleNotFoundError: No module named 'tools.nnwrap' pytorch 安装
  2. mysqldump备份单表数据
  3. 前端学习(2789):改进导航栏并跳转
  4. jquery选中以什么开头的元素
  5. 如何摇晃一瓶水使其核聚变?
  6. KITTI数据集的使用——雷达与相机的数据融合
  7. ubuntu 14.04 16.04 安装caffe+cuda8.0+pycafee总结
  8. ElasticSearch的搜索推荐(typeahead)
  9. Office for Mac升级提醒如何去掉?关闭Mac的Microsoft AutoUpdate弹框提示
  10. python大众点评霸王餐_大众点评-每天自动抽取霸王餐
  11. Python 模块:XlsxWriter 的使用
  12. Socket聊天室(基于C语言)
  13. 牛腩--SQLHelper
  14. springboot bootcdn使用
  15. solidworks2014方程式添加全局变量存在句法错误的解决方案
  16. cordova 图标设置
  17. 几何学五大公理_几何学的五个公理是什么?
  18. performance性能监控
  19. android 设置布局宽度,Android布局宽度为50%
  20. 键盘钢琴(有空进来弹弹琴,真的可以弹的)

热门文章

  1. Serverless五大优势,成本和规模不是最重要的,这点才是架构
  2. 深入JVM彻底剖析前面ygc越来越慢的case
  3. 设计模式之单例模式实践
  4. Consul入门07 - Consul Web界面
  5. tomcat 终止端口号时 taskkill /pid 17292 /f 中/f是什么意思
  6. java异步框架feed,Java:IO流里面的BuffeedReader
  7. aspx网页背景图片设置代码_python 30行代码自动填写问卷(单选题和多选题)
  8. 北京排查利用数据中心挖矿,IDC矿场受影响较大
  9. 字节跳动践行节能减排,数据中心能效居行业前列
  10. 湿度传感器如何工作?