文档章节

JavaScript之作用域

liu_yong
 liu_yong
发布于 2016/11/27 12:45
字数 1386
阅读 9
收藏 1
点赞 0
评论 0

     几乎所有的编程语言都有作用域的概念,而且理解该门语言作用域是掌握这门语言的必经之路。如果你要访问某个变量或函数,作用域则决定了你能否访问到,换句话说作用域控制着变量与函数的可见性和生命周期。

    记得刚刚学js的时候(其实当时压根没怎么学js,按照对Java的理解就直接开始用了),对于js的作用域这块完全是按照Java的作用域来理解的,结果就这样写点简单的js倒也没有太大的问题,但是后来业务越来越复杂,需要写的js也越来越复杂,就发现js的作用域和Java的不一样呢!(对于Java和JavaScript之间的关系还有疑问的同学,只需要记住这两种语言的共同点就是名字都含有Java就是了。)那么js的作用域是怎么的样呢?下面我们就说道说道。

    在js里面,以函数来分隔作用域,又称函数作用域: 作用域在函数内修改。 如:

function scopeFunc(){
	for(var i=0;i<5;i++){
		//console.log(i);
	}
	console.log(i);
}
scopeFunc();//5
//如果js有块级作用域,那么在for循环外应该是取不到i的值的,应该报错,但是我们照样取到了i的值;这里的i是局部变量

function scopeFunc2(){
	for(let i=0;i<5;i++){
		//console.log(i);
	}
	console.log(i);
}
scopeFunc2();//i is not defined
//在ES6(ES2015)之前,我们看到js是没有块级作用域的,但是ES6新有的定义变量的let关键字,可以定义块级作用域

function Student(name){
	console.log(name);//ly
	var score;
	console.log(score);//undefined
	console.log(age);//ReferenceError: age is not defined
}
Student('ly');
console.log(name);//undefined;函数参数只在函数内起作用,是局部变量。
//我们看到在函数内使用一个定义了但是未赋值的变量的时候,提示undefined,使用一个未定义的变量时提示出错了。

//scopeFunc是函数的句柄,在js中,对象和函数同样也是变量,此处,scopeFunc是全局函数,也是全局变量了
setTimeout(scopeFunc,500);
//setTimeout这里用的是函数的句柄,如果写成setTimeout(scopeFunc(),500);会造成内存泄露

/*
最外层函数和在最外层函数外面定义的变量拥有全局作用域,所以声明全局变量比较简单,不过有种特殊的情况,在函数内,
如果不使用var声明,直接给变量赋值,这个变量直接就拥有全局作用域
*/
function wholeScopeFn(){
	testw='imwhole';//如果不使用var声明变量,此处就相当于是window.testw='imwhole';
	var testpart='impart';
	console.log(testpart);
}
console.log(testw);//ReferenceError: testw is not defined 
wholeScopeFn();//impart
console.log(testw);//imwhole
/*
全局变量我们都可以通过window.变量名 的方式来获取,但是当使用var声明一个全局变量时,
创建的这个属性是不可配置的,也就是说无法通过delete运算符删除,不使用var声明的全局变量,可以通过delete删除
*/

//函数运行在它们被定义的作用域里,而不是它们被执行的作用域里
function Student(name){
	console.log(name);//ly
	var score;
	console.log(score);//undefined
	console.log(age);//ReferenceError: age is not defined
}
function myCare(){
	var age=10;
	Student('ly');
}
myCare();
//我们看到,myCare函数内已经声明并初始化了一个变量age,而在Student函数内,在执行到打印age变量的时候任然提示为定义

    总结一下就是变量在函数外定义,就是全局变量。 变量在函数内声明,就是局部变量, 只能在函数内部访问。

    说了变量的作用范围,还得说说变量的生命周期。生命周期意味着你用了当前变量之后下次用的时候他得是个什么。简单的说,变量在他还能被用到的时候就不会被销毁,不能再被用到的时候就该销毁了,生命也就走到尽头了。如:

function scopeLife(){
	var sl=0;
	console.log(++sl);
}
var wsl=0;
scopeLife();//1
scopeLife();//1
scopeLife();//1 ;局部变量在函数执行完毕后销毁。
console.log(++wsl);//1
console.log(++wsl);//2
console.log(++wsl);//3 ;全局变量在页面关闭后销毁。

    好的,我们再来看看和作用域有关的一个有趣的地方,变量声明提升。

var name='ly';
function Student(){
	console.log(name);//undefined
	var name='liuyong';
	console.log(name);//liuyong
}
//上面的代码可以写成如下
var name='ly';
function Student(){
        var name;
	console.log(name);//undefined
	name='liuyong';
	console.log(name);//liuyong
}
//这样是不是好理解得多了,当执行函数的时候,会先函数内的变量的声明。

//如果函数内不写var直接定义全局变量,这样的变量是不会被提升的
function Student(){
	console.log(name);
	name='liuyong';
	console.log(name);//liuyong
}
Student();

    说到js作用域,如果不说作用域链,会不会显得太低端了呢?哈哈,可以看下这两篇文章(JavaScript作用域链详细介绍JavaScript 开发进阶:理解 JavaScript 作用域和作用域链),个人觉得作用域链这块,这两篇文章讲得挺不错的。有什么问题也欢迎交流。

© 著作权归作者所有

共有 人打赏支持
liu_yong
粉丝 1
博文 21
码字总数 30353
作品 0
成都
前端工程师
JavaScript的变量作用域

在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的。 JavaScript没有块级作用域。 函数中声明的变量在整个函数中都有定义。 1、JavaS...

biGpython
2011/08/13
0
0
JavaScript中的this指针 理论化this指针的定义

JavaScript现在应用之广泛,远超其他任何语言,只要是一个合格的网站应用,基本上多多少少都会有JS的存在。在JavaScript中,this的指向被不少Coder所不解,但其实JS中的this理解起来也是相当...

superwebmaster
05/29
0
0
图解Javascript上下文与作用域

本文尝试阐述Javascript中的上下文与作用域背后的机制,主要涉及到执行上下文(execution context)、作用域链(scope chain)、闭包(closure)、等概念。 >> 原文 << Execution context 执...

rainyear
2015/07/06
0
7
JavaScript作用域 - 学习Javascript的基石之一(转)

1.作用域 JavaScript的作用域与C、Java等语言不同,它不是以花括号包围的块级作用域,这个特性经常被大多数人忽视。例如下面代码,在大多数类C的语言中会出现变量未定义的错误,但在JavaScr...

顽Shi
2014/02/13
0
0
翻译 - JavaScript中的作用域与变量声明提升

本文地址:http://blog.163.com/jinluhz/blog/static/113830152201131132035178/ 原文地址:http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting 原文作者:ben cherry ......

蜗牛奔跑
2015/06/19
0
0
Atom飞行手册翻译: 4.3 作用域设置、作用域和作用域描述符

作用域设置、作用域和作用域描述符 Atom支持语言特定的设置。你可以在Markdown文件中软换行,或者在Python中把tab的宽度设置为4。 语言特定的设置只是一些东西的子集,我们把它叫做“作用域设...

apachecn_飞龙
2015/08/07
0
0
Function执行原理 & 闭包

Execution Context 执行期上下文 在java或c语言中,都有块级作用域这个概念,而js中则没有。 在js中,作用域只有一种,即函数级作用域。 而执行期上下文,可以理解为函数的作用域或执行环境。...

烽穹寒渊
07/13
0
0
Function执行原理 & 闭包

Execution Context 执行期上下文 在java或c语言中,都有块级作用域这个概念,而js中则没有。 在js中,作用域只有一种,即函数级作用域。 而执行期上下文,可以理解为函数的作用域或执行环境。...

烽穹寒渊
2016/08/21
0
0
关于javaScript的认识

NaN与Infinity和-Infinity不同的是,NaN不会与任何数值变量相等,可以用javaScript专门提供的isNaN()函数来判断某个变量是否为NaN。 Undefined类型的值只有undefined一个,该值用于表示某个变...

杨松坤
2012/05/09
0
0
谈谈javascript语法里一些难点问题(二)

原文出处:夏天的森林 3) 作用域链相关的问题 作用域链是javascript语言里非常红的概念,很多学习和使用javascript语言的程序员都知道作用域链是理解javascript里很重要的一些概念的关键,这...

夏天的森林
2014/12/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

知识点总结

jq如何拿到data-info的自定义属性 1.1 原生可以获取到所有属性el.attrbutes 1.2 jq的$(el).attr('属性名称') 继承的几种方式,原型链 2.1 扩展原型对象实现继承 2.2 替换原型对象实现继承 2....

litCabbage
9分钟前
0
0
python语言规范

http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/...

ghou-靠墙哭
13分钟前
0
0
istio 监控,遥测 (理论)

Istio提供了一种灵活的模型来强制执行授权策略并收集网格中服务的遥测。 基础架构后端旨在提供用于构建服务的支持功能。它们包括诸如访问控制系统,遥测捕获系统,配额执行系统,计费系统等之...

xiaomin0322
16分钟前
0
0
阿里资深专家面试问题收集

corejava hashcode相等的两个对象一定相等吗?equals呢?反过来相等吗? 介绍一下集合框架? hashtable,hashmap底层实现是什么?hashtable和concurrenthashmap底层实现的区别? hashmap和treemap的...

undefine
17分钟前
6
0
alpine安装软件指定安装源

linux-alpine安装软件指定安装源 一、永久修改apk下载源地址 vi etc/apk/repositories 替换成阿里源 http://mirrors.aliyun.com/alpine/v3.8/main/http://mirrors.aliyun.com/alpine/v3...

我心中有猛狗
17分钟前
0
0
Centos7通过yum安装nginx

添加源地址(直接install可能不是最新版本的) sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 安装 sudo yum install -y ng......

iplusx
19分钟前
0
0
ef .core Dapper Helper

using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Threading.Tasks; using Dapper; using Dap......

Lytf
21分钟前
0
0
iOS 小笔记

1.以下代码打印什么     __block int val = 10;    void (^blk)(void) = ^{        printf("val=%d\n",val);        };       val = 2;    blk(); /...

风了个1
22分钟前
0
0
【Spring Boot 系列 Spring Boot示例程序】

入门程序步骤,创建一个Maven项目。继承Spring Boot官方提供的父工程。再引入一个Web的应用启动器。 1、选择一个合适的IDEA工具 创建一个Maven工程,并添加如下配置 <parent> <...

HansonReal
24分钟前
0
0
217. Contains Duplicate - LeetCode

Question 217. Contains Duplicate Solution 题目大意:判断数组中是否有重复元素 思路:构造一个set,不重复就加进去,重复返回true,如果数据量大的话,可以用布隆过滤器 Java实现: publ...

yysue
28分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部