深入理解JavaScript的函数作用域
什么是作用域 ?
作用域:一个变量可以生效的范围。 变量不是在所有地方都可以使用的,而这个变量的使用范围就是我们要说的作用域。
注意:在JavaScript中,划分作用域也是用大括号划分的, 但是在 JS 之中能够有效限定作用域的大括号只有函数大括号!
有哪些作用域 ?
- 全局作用域(不再任何函数内)
学习使用作用域,以下内容是所需要了解的:
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
- 这个全局作用域会一直存在,直到页面关闭才会销毁
请看下面示例代码:
var a = 10;
console.log(a); // 输出结果: 10
function foo(){
console.log(a); // 输出结果: 10
}
foo()
当变量 a 声明时,没有被函数大括号包裹, 那么这个变量我们称之为 全局变量
这个全局变量在任何地方都可以访问。
- 局部作用域(在函数内部)
同样的,以下内容也是所需要了解的:
- 局部作用域就是在全局作用域下面开辟出来的一个相对小一些的作用域
- 在局部作用域中定义的变量只能在这个局部作用域内部使用
- 在 JS 中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
请看下面示例代码:
function foo(){
var a = 10; //在大括号之中声明的变量只能在这个大括号之中使用;
console.log(a); // 输出结果: 10
}
foo();
console.log(a); // 报错 => ReferenceError: a is not defined
通过上面示例代码可以看出:
在函数大括号之中声明的变量,这种变量我们称之为 局部变量 !
局部变量只能在声明它的作用域之中使用;
我们见惯了常规情况,现在看一个特殊情况:
声明变量时不使用 var 关键字声明:
注意!这是一个不规范的声明方式!不要使用!不要使用!不用使用!
使用之后导致的结果就是:一个局部变量的声明,在全局中也可以被访问了!( 这样的声明叫做 伪全局变量 )
请看下面示例代码:
function foo(){
a = 10; // 此时声明变量 a 没有使用var关键字声明
console.log(a); //
}
foo();
console.log(a); // 输出 10,不报错了;
看完上面的代码示例,你是不是觉得这不挺好的嘛,变量 a 可以随便使用,都不用报错了,为什么不让使用??
呵呵,别高兴太早,继续往下看,你的这个想法很危险的!
当把局部变量变成伪全局变量:
你会发现:
- 生命周期变长,造成一定的负面影响;
- 占据了全局命名空间,造成不可预知的错误
是不是脑子里突然蹦出了好多问题:生命周期是什么鬼?命名空间又是什么鬼??
好吧,上面这个内容我说早了,那么接着往下看:
全局变量和局部变量的区别:
在这里就来聊一下上面的生命周期和命名空间吧!
生命周期(这个变量在内存之中存活的时间)
就是你啥时候可以访问!
- 全局变量:生命周期是和程序同步的, 程序不关闭,变量就一直存在;
导致的结果就是会让程序变得更重! 如果可能,还是少设计一点全局变量吧!对大家都好
- 局部变量:生命周期是和函数执行同步的,函数执行结束变量就被删除了;
现在知道啥是生命周期了吧,全局变量多了,可能真的会影响到我们程序的运行效率,上面说的伪全局变量就是这个道理。
我们看完了生命周期,再来一起看一下命名空间吧!
命名空间(变量名命名的唯一性)
- 全局变量:命名空间是唯一的,一个页面只有一个
我们先来举一个小例子,话不多说上代码:
var count = 10;
function foo(){
// 我的代码 : 我的私人领域;
// 程序的懒惰原则:函数的大括号之中如果已经有了查找结果,那么就不会继续再查找了;
// 就近原则;
var count = 0;
console.log(count); // 运行结果:0
}
foo();
console.log(count); // 运行结果:10
为了解决全局之中的命名空间是唯一的这个问题,我们可以把这个变量放在局部,那么就不会占用全局的命名空间了。
- 局部变量:命名空间一个作用域一个
可以用匿名函数来解决命名空间的问题
最后一个问题:我现在要写一大坨代码,和别人的代码要配合 。 这个时候咋写呢???
我可以把代码写在一个没有名字的函数之中! 什么?这样写直接报错 ?
JS为啥阻止他 ? 如果我立即调用呢!来一个瞒天过海如何?
让匿名函数经历一次运算: 如果函数发生了特定的运算, 那么这个函数就会被当做一个地址;
// 让匿名函数经历一次运算: 如果函数发生了特定的运算,那么这个函数就会被当做一个地址;
// var res = 1 + function(){}
// console.log(res); //运行结果:1function(){} // 利用这个机制使用匿名函数立即调用 :
// +function(){
// console.log("hello world")
// }(); // 函数经过运算变成了地址,被后面的调用运算符调用了;
// !function(){
// console.log("hello world")
// }(); // 一种普遍的写法 : // (function(){
// console.log("hello world1");
// })()
// 可能存在的bug;
// (function(){
// console.log("hello world1");
// })();
// //两个匿名函数同时是使用一定要加上分号
// (function(){
// console.log("hello world2");
// })();
// 建议写法;
;(function(){
console.log("hello world1");
})();
最后来个总结吧!
1、全局不能访问局部
2、局部可以拿到全局
喜欢的朋友可以点点关注,点点赞,欢迎评论区留言互动。
深入理解JavaScript的函数作用域的更多相关文章
- 深入理解 JavaScript 变量的作用域和作用域链
一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...
- javascript篇-----函数作用域,函数作用域链和声明提前
在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的(也就是我们不能在代码段外直接访问代码段内声明的变量),我们称之为块级作用域,然而,不同于 ...
- 理解javascript 回调函数
##回调函数定义 百度百科:回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数.回调函数不 ...
- 深入理解JavaScript中的作用域和上下文
介绍 JavaScript中有一个被称为作用域(Scope)的特性.虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域.理解作用域将使你的代码脱颖而出,减 ...
- JavaScript之函数作用域
有过类似C语言编程经验的同学应该都知道“块级作用域(block scope)”:花括号内的每一段代码都具有各自的作用域,而且在声明它们的代码段之外是不可见的.而在JavaScript中是没有块级作用域 ...
- 谈谈javascript的函数作用域
在一些类似c语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明他们的代码段之外是不可见的,我们称为块级作用域(block scope),而javascript中没有块级作用域.取 ...
- 理解 JavaScript 回调函数并使用
JavaScript中,函数是一等(first-class)对象:也就是说,函数是 Object 类型并且可以像其他一等对象(String,Array,Number等)一样使用.它们可以"保 ...
- 理解JavaScript中的作用域和上下文
JavaScript对于作用域(Scope)和上下文(Context)的实现是这门语言的一个非常独到的地方,部分归功于其独特的灵活性. 函数可以接收不同的的上下文和作用域.这些概念为JavaScrip ...
- 深入理解JavaScript中的作用域、作用域链和闭包
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qappleh/article/detai ...
随机推荐
- 6)PHP,预定义变量
预定义变量也叫超全局变量: :预定义变量又叫超全局变量,包括: $_GET, $_POST, $_SERVER, $_REQUEST, $GLOBALS, $_COOKIE, $_SESSION, . ...
- Java中的堆、栈、方法区
堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对 ...
- 14 微服务电商【黑马乐优商城】:day04-项目搭建(一)
本项目的笔记和资料的Download,请点击这一句话自行获取. day01-springboot(理论篇) :day01-springboot(实践篇) day02-springcloud(理论篇一) ...
- 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...
- 吴裕雄--天生自然C语言开发:数组
] = {1000.0, 2.0, 3.4, 7.0, 50.0}; ]; #include <stdio.h> int main () { ]; /* n 是一个包含 10 个整数的数组 ...
- Qt 信息提示框 QMessageBox
information QMessageBox::information(NULL, "Title","Content",QMessageBox::Yes | ...
- 【学习笔记】 Johnson 全源最短路
前置扯淡 一年多前学的最短路,当时就会了几个名词的拼写,啥也没想过 几个月之前,听说了"全源最短路"这个东西,当时也没说学一下,现在补一下(感觉实在是没啥用) 介绍 由于\(spf ...
- Cisco路由器配置基本命令
特权模式:enable Router1 # show running-config Router1 # show ip route Router # show ip interface brief S ...
- JavaScript--DOM,BOM
前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...
- LeetCode No.85,86,87
No.85 MaximalRectangle 最大矩形 题目 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积. 示例 输入: [ ["1", ...