javascript进阶系列专题:作用域与作用域链
字面意思,作用域是指变量和函数的作用范围,换言之,作用域决定了变量和函数的可见性和有效时间。javascript作用域是用函数来区分,与其他语言的大括号不同。
for (var i=0; i<5; i++){
var mystring = "平底斜";
console.log(i);
}
alert(mystring);//弹出"平底斜"
这段代码在javascript中运行正常,在其他语言中就会报错。这是因为javascript的作用域是基于函数,而不是大括号。
作用域分为全局作用域和局部作用域。
有三种情况会出现全局作用域:
1、最外层定义的变量和函数
var mystring = "平底斜";
function fun(){
alert("Hello World");
}
变量mystring和函数fun()拥有全局作用域,在任何位置都可以直接调用。
2、未定义的变量
function fun(){
var a=b=0;
mystring = "平底斜";
console.log(mystring);
}
fun();
alert(b);
变量mystring没有使用var进行变量声明,所以即使在函数内部也是全局变量。容易忽略的是变量b,看上去使用var进行了声明,实际上只对变量a进行了声明,等同于
function fun(){
var a=(b=0); //自右向左赋值
mystring = "平底斜";
console.log(mystring);
}
一个JS文件中应该尽可能少的出现全局变量,最佳实践是使用var进行变量声明,并且在声明的同时进行赋值。
function fun(){
var a=0, b=1, c=2; //等同于var a=0; var b=1; var c=2;
}
fun();
alert(c); //脚本报错,因为c是局部变量
3、全局对象window
var mystring = "平底斜";
console.log(mystring);
console.log(window.mystring);
console.log(window["mystring"]);
console.log(this.mystring);
console.log(this["mystring"]);//此处this就是window,针对this以后会专题讲解
全局变量都可以看做window的属性,使用方法就如以上代码:可以用"."也可以用"[]"甚至可以省略window
局部变量只有一种情况:在函数内部声明的变量拥有局部作用域
function fun(){
var mystring="平底斜"; //局部变量
console.log(mystring);
}
fun();
console.log(mystring); //脚本报错
冷知识:
全局变量中,使用var声明与不使用var是有区别的,var声明的变量无法删除,未声明的变量可以删除。
var mystring="平底斜";
newstring = "博客园";
delete mystring;
delete newstring;
console.log(mystring); //"平底斜"
console.log(newstring); //脚本报错
作用域链由内向外查找变量,在内部找到变量便停止查找,否则往上一层作用域查找,直到最外层都没有找到变量则返回undefined
var myscope = "平底斜";
function fun(){
var myscope = "博客园";
console.log(myscope); //"博客园"
}
fun();
上面这段代码,就是因为作用域链有内向外,先在函数内部查找myscope,找到了就直接返回该变量值,并停止查找。
易错点:
var myscope = "平底斜";
function fun(){
console.log(myscope); //脚本报错
var myscope = "博客园";
console.log(myscope); //"博客园"
}
fun();
声明变量会在当前作用域中置顶,又叫变量提升或者声明置顶。以上代码等同于:
var myscope = "平底斜";
function fun(){
var myscope;
console.log(myscope); //脚本报错
myscope = "博客园";
console.log(myscope); //"博客园"
}
fun();
需要注意的是变量提升是在函数定义时发生,并不是在函数调用时:
var myscope = "平底斜";
function fun1(){
console.log(myscope);
}
function fun2(){
var myscope = "博客园";
fun1();
}
fun2(); //"平底斜"
如上,fun2()调用fun1()时,是先在fun1()中搜索myscope,找不到时再到父级作用域中查找。作用域的嵌套关系是在定义时产生,而不是在调用的时候。
javascript进阶系列专题:作用域与作用域链的更多相关文章
- javascript进阶系列专题:闭包(Closure)
在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中. var fun = function(){ console.log("平底斜"); } f ...
- JavaScript进阶系列07,鼠标事件
鼠标事件有Keydown, Keyup, Keypress,但Keypress与Keydown和Keyup不同,如果按ctrl, shift, caps lock......等修饰键,不会触发Keyp ...
- JavaScript进阶系列06,事件委托
在"JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数"中已经有了一个跨浏览器的事件处理机制.现在需要使用这个 ...
- JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
本篇体验JavaScript事件的基本面,包括: ■ 事件必须在页面元素加载之后起效■ 点击事件的一个简单例子■ 为元素注册多个点击事件■ 获取事件参数 ■ 跨浏览器事件处理 □ 事件必须在页面元素加 ...
- JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
本篇主要体验函数参数个数不确定情况下的一个解决方案.先来看一段使用函数作为参数进行计算的实例. var calculate = function(x, y, fn) { return fn(x, y) ...
- JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
本篇体验通过硬编码.工厂模式.构造函数来创建JavaScript对象. □ 通过硬编码创建JavaScript对象 当需要创建一个JavaScript对象时,我们可能这样写: var person = ...
- JavaScript进阶系列02,函数作为参数以及在数组中的应用
有时候,把函数作为参数可以让代码更简洁. var calculator = { calculate: function(x, y, fn) { return fn(x, y); } }; var su ...
- JavaScript进阶系列01,函数的声明,函数参数,函数闭包
本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...
- JavaScript学习系列博客_20_JavaScript 作用域
作用域 - 作用域指一个变量的作用的范围 - 在JS中一共有两种作用域 1.全局作用域 - 直接编写在script标签中的JS代码,都在全局作用域- 全局作用域在页面打开时创建,在页面关闭时销毁 - ...
随机推荐
- Swift设置textView的行间距
let textview = UITextView(frame: CGRect(x: 100, y: 100, width: 100, height: 200)) let paraph = NSMut ...
- java 线程返回值
1.传统方式需要新建一个接口类,然后在接口类中将结果在方法中作为参数进行处理 package de.bvb.test3; public class Test3 { public static void ...
- Dynamics AX 2012 R2 如何处理运行时间较长的报表
当处理的数据量较多,逻辑比较复杂时,报表可能会超时.为了解决这个问题,Reinhard一直使用SrsReportDataProviderPreProcess来做预处理报表.它会在调用SSRS前,在AX ...
- python :开关,开灯关灯
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- (转)漫谈SOA(面向服务架构)
http://blog.csdn.net/luohuacanyue/article/details/12521699 面向服务架构的思想在整个软件的架构中已经不是什么新鲜的东西.我简单的认为服务化是模 ...
- 亚马逊EC2弹性IP收费
刚收到亚马逊云账单,被扣了4.44刀,吓尿,麻溜的去查账单详情,发现之前弃用的美国实例有个弹性IP没释放掉,占着茅坑还不拉屎,被扣钱宝宝无话可说,赶紧释放... $0.005 per Elastic ...
- jquery常用总结
1.遍历对象 n是属性 value是对应的值 $.each(param,function(n,value) { datas[n] = value; }); 2.获取select改变后的值 $('sel ...
- 完整安装cocoaPods
cocoaPods是一款xcode项目管理第三方库的工具 *ruby源码镜像下载:https://ruby.taobao.org/mirrors/ruby/*升级gem的版本: $sudo gem u ...
- ZooKeeper测试笔记
1. 下载ZooKeeper.官网:http://zookeeper.apache.org 下载后解压,假定zookeeper程序目录为/home/test/zookeeper,为陈述方便此目录记为 ...
- 一位程序员如何修炼成CTO
几乎整个互联网行业都缺CTO,特别是一些草根背景的创业者,这个问题更加显著.从我自己的感受,身边各种朋友委托我找CTO的需求,嗯,算下来超过两位数了,光最近一个月就有3个,而且这三家都是刚拿了A轮的. ...