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代码,都在全局作用域- 全局作用域在页面打开时创建,在页面关闭时销毁 - ...
随机推荐
- 日文xp系统中 日文键盘模式转英式键盘模式
键盘设备驱动早在Windows XP安装时就已经安装好了,但是系统却将日式键盘误识成了美式标准键盘,这会出现一些标点符号的实际输入与键盘标注不符的问题,对于用惯了英文键盘的人可 以盲打而不去理会,但对 ...
- 突击战UVa11729Commando War
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=117&page= ...
- Edittext默认无焦点
开发中,发现第一次进入页面时光标就会出现在页面的第一个edittext中,解决思路是: 在edittext的父布局中加入两行代码夺取焦点 <com.zhy.autolayout.AutoLine ...
- 常用SQL总结
数据库知识总结一.数据库服务器设置1,查看数据库服务器编码 show variables like 'character%';2,设置数据库服务器编码 set character_set_ ...
- C语言-自定义函数
C语言自定义函数 --1-- 自定义函数定义 1.1 无参无返回值函数 1.2 无参有返回值函数 1.3 有参无返回值函数 1.4 有参有返回值函数 --2-- 函数的参数 2.1 形式参数介绍和使用 ...
- android 获取设备拔插状态广播事件易漏掉的一行属性!
我们都知道设备拔插的状态获取需要一个权限 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILES ...
- Web App适配不同屏幕的几点建议
安卓设备在屏幕尺寸和像素密度上差别很大,因此在使用WebView加载网页时就需要考虑到这种差别,对我们的网页做出精心的设计以在不同的屏幕上都能得到合适的展现.通常情况下,我们需要考虑到两个因素:1.视 ...
- [Machine-Learning] K临近算法-简单例子
k-临近算法 算法步骤 k 临近算法的伪代码,对位置类别属性的数据集中的每个点依次执行以下操作: 计算已知类别数据集中的每个点与当前点之间的距离: 按照距离递增次序排序: 选取与当前点距离最小的k个点 ...
- [转]NandFlash和NorFlash的区别
一. NAND和NOR的比较 NOR和NAND是现在市场上两种主要的非易失闪存技术.Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM 和EEPROM一统天下的局面.紧 ...
- ECMAScript数组常用
var arr = [22, 33, 44, 55, 66, 77, 88, 99]; //every 全部结果为true 则返回true var e = arr.every(function (m) ...