javascript练习题(2):变量作用域
1. 外层变量在内部可以找到,反之找不到
以下看个案例:
var a=10;
function aaa(){
alert(a);
}
function bbb(){
var a=20;
aaa();
}
bbb();
结果是?
aaa()和外层的a=10处于同一个变量作用域。所以只能查找10.
如果把a=10去掉呢?结果是报错了。
还是变量作用域的问题,aaa的环境在全局环境下,不可能找到bbb里面的a=20.
2. var的问题:不var就是全局变量
var不写也是可以的。但是不写可能产生一些问题——变量会变成一个全局变量!
由此衍生出这样的问题:
function aaa(){
var a=b=10;
}
aaa();
alert(a);
alert(b);
回想问题,b变成了一个全局变量,a是一个局部变量。
所以alert(a)会报错。
去掉alert(a),aaa()运行的结果是产生了一个全局变量b和一个局部变量a。所以alert(b)的结果是10。
3.变量查找是就近原则,寻找var定义的变量
var a=10;
function aaa(){
alert(a);
var a=20;
}
aaa();
结果是什么?
既不是10也不是20。是undefined
当就近未找到,就会查找外层。一层一层知道直到找到为止。把结果简化一下吧:
var a=10;
function aaa(){
var a=20;
alert(a);
}
aaa();
结果是20。这很符合常识的推断。
var a=10;
function aaa(){
a=20;
alert(a);
}
aaa();
弹出a也是20,但是运行过程需要注意:最开始查找10,接着查找内部,发现a被修改为20.——本质是调用了外层的a。
好了。现在回到本节最初的例子,aaa调用alert的时候,查找的是外层的a,这个进程遇到var a=20这一步时,由于函数内部预解析,查找的作用域就变了。开始查找函数内部的a,但是var a=20这一步放在了后面,所以结果是undefined。
实际上代码变成了这样:
var a=10;
function aaa(){
var a;
alert(a);
a=20;
}
aaa();
所以所有变量在定义时必须放最前面、
4.结合分析
var a=10;
function aaa(){
bbb();
alert(a);
function bbb(){
var a=20;
}
}
aaa();
的结果是什么?
弹出结果是10。因为a是局部中的局部,说白了找不着。
那如果这么写呢?
var a=10;
function aaa(){
bbb();
alert(a);
function bbb(){
return a=20;
}
}
aaa();
好了。由于函数的预解析作用,导致bbb执行修改了全局变量a。所以弹出结果是20.同理,如果我把全局变量var a=10删去。结果还是20。因为bbb又创造了一个全局变量a。
5. 参数跟局部变量同名,优先级是等同的
var a=10;
function aaa(a){
alert(a);
}
aaa(a);
这个简单的例子中弹出的是10。
如果把参数改成b,
var a=10;
function aaa(b){
alert(a);
}
aaa();
结果还是10.
那么这个a究竟是参数呢,还是全局变量a?
答案是,参数名和全局变量名一样时,走的是参数,不一样时,走的是全局变量。
比如:
var a=10;
function aaa(a){
a+=3;
}
aaa(a);
alert(a);//结果是10
基本数据类型不存在引用关系,里面的a就是一个局部变量
看个纠结一点点的吧:
var a=5;
var b=a;
b+=3;
alert(a)
a是5。这是常识。
基本类型的赋值是不存在引用关系的。但如果我想让a和b存在引用关系,应该怎么做?
var a={
a:5
}
var b=a;
b.a+=3;
console.log(a);//{a:8}
如果不存在依存关系——
var a={
a:5
}
var b={
a:a.a
};
b.a+=3;
console.log(a);
另外一个简单例子是数组。
假设这样
var a=[1,2,3];
var b=a;
b.push(4);
console.log(a);//[1,2,3,4]
所以真的要小心了。如果你不想存在引用关系,应该
var b=a.slice()
复合对象应用关系还可以衍生出这样的操作:
var a=[1,2,3];
function aaa(a){
a.push(4);
}
aaa(a);
console.log(a);//[1,2,3,4]
真是没有做不到,只有想不到,这个a又是什么鬼?不是局部变量吗?
a是确实是局部变量没错,但是它引用了外部的数组a。对这个局部变量的操作必将导致外部a的改变!
下面的代码或许让人更清醒些——
var a=[1,2,3];
function aaa(a){
a=[1,2,3,4]
}
aaa(a);
console.log(a);//[1,2,3,4]
因为参数a没有引用外部的a,所以怎么操作都跟外部的a没半毛钱关系!
javascript练习题(2):变量作用域的更多相关文章
- javascript中的变量作用域以及变量提升
在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解. 变量作用域 “一个变量的作用域表示这个变量存在的上 ...
- JavaScript基础——理解变量作用域
一旦你开始在JavaScript应用程序中添加条件.函数和循环,就需要理解变量作用域.变量作用域规定了如何确定正在执行的代码行上的一个特定变量名的值. JavaScript允许你既定义全局版本又定义局 ...
- javascript中的变量作用域以及变量提升详细介绍
在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解变量作用域 “一个变量的作用域表示这个变量存在的上下文 ...
- 【JavaScript 从零开始】变量作用域
变量作用域 一个变量的作用域(scope)是程序源代码中定义这个变量的区域. 全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的.然而在函数内声明的变量只是函数体内有定义. 他 ...
- JavaScript学习系列2一JavaScript中的变量作用域
在写这篇文章之前,再次提醒一下 JavaScript 是大小写敏感的语言 // 'test', 'Test', 'TeSt' , 'TEST' 是4个不同的变量名 JavaScript中的变量,最重要 ...
- JavaScript要点 (一) 变量-作用域
JavaScript 作用域 作用域—可访问变量的集合. 全局变量或者函数可以覆盖window对象的变量或者函数: 局部变量和window对象可以覆盖全局变量和函数. JavaScript 作用域 在 ...
- javascript中的变量作用域
在网上看了一道js面试题 <script type="text/javascript"> var tt = 'aa'; function test() { alert( ...
- javascript痛点之一变量作用域
1.用var声明的变量是有作用域的,比如我们在函数中用var声明一个变量 1 'use strict'; 2 function num(){ 3 //用var声明一个变量num1 4 var num1 ...
- 【Javascript系列】变量作用域
问题描述 本篇文章主要讲解javascript变量及其作用域. 1 内容区 在js中,变量大致可分为全局变量(全局作用域)和局部变量(局部作用域): 用关键字var定义变量(全局变量,可以省略va ...
- JavaScript练习题 全局变量 局部变量 作用域
前沿:大家好~我是阿飞~本次 任何简单的事情都可以复杂化,本次让我们来做下搞事情的练习题吧 例题1: var a = 1; function fn1(){ var a = 2; alert(a); / ...
随机推荐
- convention over configuration 约定优于配置 按约定编程 约定大于配置 PEP 20 -- The Zen of Python
为什么说 Java 程序员必须掌握 Spring Boot ?_知识库_博客园 https://kb.cnblogs.com/page/606682/ 为什么说 Java 程序员必须掌握 Spring ...
- 学习js的正确姿势
轻松入门: http://dwz.cn/6yYLoo 全面理解: http://www.shouce.ren/api/view/a/1116 大师进阶: http://es6.ruanyifeng.c ...
- [荐][转]为何应该使用 MacOS X(论GUI环境下开发人员对软件的配置与重用)
一周前我和 Tinyfool 闲聊苹果操作系统,都认为对于开发人员来说,苹果操作系统(MacOS)是上佳的选择.Tinyfool 笔头很快,当即就写了一篇长文章,我则笔头很慢,今天才全部码好.他的文章 ...
- Python菜鸟之路:Django 缓存
Django中提供了6种缓存方式: 开发调试 内存 文件 数据库 Memcache缓存(python-memcached模块) Memcache缓存(pylibmc模块) 1. 开发调试 # 此为开始 ...
- windows7上使用docker容器
1.安装 下载DockerToolbox,并安装. 下载地址:https://dn-dao-github-irror.daocloud.io/docker/toolbox/releases/downl ...
- Django的模型层(2) - 多表操作(下)
一.多表查询 1.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接 ...
- 重读C库之宏定义
1.如何编写头文件.h? //file--func1.h #ifndef __FUNC1_H //__func1_h //可小写可大写 #define __FUNC1_H //__func1_h .. ...
- 安装MySQL版本为mysql-installer-community-5.7.17.msi
双击MySQL安装包, 勾选复选框,点击下一步: 选择仅仅服务器模式,点击下一步: 直接点击执行: 执行完成,点击下一步: 确认配置,点击下一步: 输入用户名和密码,点击下一步: 默认选项,点击下一步 ...
- PHP使用Mongodb
一.安装Mongodb的PHP扩展 wget http://pecl.php.net/get/mongo-1.2.7.tgz //下载扩展包tar zxvf mongo-1.2.7.tgzcd mon ...
- NIO服务端和客户端通信demo
代码转自 https://www.jianshu.com/p/a9d030fec081 服务端: package nio; import java.io.IOException; import jav ...