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代码,都在全局作用域- 全局作用域在页面打开时创建,在页面关闭时销毁 - ...
随机推荐
- 进制转换及API接口中的转换
//十进制转二进制Console.WriteLine("十进制166的二进制表示: "+Convert.ToString(166, 2));//十进制转八进制Console.Wri ...
- VS2010无法调试问题解决
最近,因为公司开发的需要,对开发环境进行全面的升级,在这其中也遇到了不少问题,在之后将陆续整理出来,以便以后查看. 之前开发环境:VS2008,ArcGIS9.3,ArcEngine9.3,Oracl ...
- java在图片上添加文字
业务需求要在图片上添加水印.下面粘出代码供自己和大家分享 package com.pro.drawTextOnImg; import java.awt.Color; import java.awt.F ...
- Mybatis框架基于映射文件和配置文件的方式,实现增删改查,可以打印日志信息
首先在lib下导入: 与打印日志信息有关的架包 log4j-1.2.16.jar mybatis架包:mybatis-3.1.1.jar 连接数据库的架包:mysql-connector-java-5 ...
- 如何输出function执行的语句
SQL> set serveroutput on;SQL> exec dbms_output.put_line(1); set serveroutput on size ...
- nginx安装及配置为简单的文件服务器
centos 6.5 直接yum安装即可 yum install nginx -y 配置文件位于:/etc/nginx/nginx.conf,里面可以修改处理器数量.日志路径.pid文件路径等,默认的 ...
- 死性不改ISO9000系列系统 2011q4~2016q1
百度云链接: http://pan.baidu.com/s/1o8rO3W2 密码: kabg 2016q2由于发布没多久,可能会重新修改,暂时不转载.
- 微信小程序开发感受
研究了大概有一个多星期的小程序了,说一下感受,之后会随时更新,一边学习,一边加上一部分学习代码和心得.我是一个前端厂里的新手,搬砖的时间不是很长,所以到一部分知识的理解浅之又浅,所以只能说自己的理解, ...
- JSON数据解析
1 JSON简介 JSON(JavaScript Object Notation),类似于XML,是一种轻量级的数据交换格式,比如在JavaEE中Struts2与Ajax在来回传递数据时,除了可以利用 ...
- [OC] Podfile 格式内容
platform :ios, '8.0' target :'targetName' do pod 'Masonry', '~> 1.0.1' pod 'SDCycleScrollView', ' ...