上一篇文章中简单介绍了一下JS作用域,本篇将作进一步探究和总结。

前言:JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,JavaScript6中新引入了 let 关键字,用于指定变量属于块级作用域,本次先忽略这个点。

第一句话:JavaScript以函数作为作用域(忽略let)

  很多语言如c#,java都是以代码块作为作用域即大括号也是一个作用域,JavaScript却是以函数作为作用域,如果你对python比较了解,理解起来应该很easy。

在c#中下面的代码将直接报错:

 public void Func(){
if(==){
string name = 'Java'; }
console.writeline(name); }
Func()
// 报错

在JavaScript语言中无块级作用域:

 function Main(){
if(1==1){
var name = 'seven';
}
console.log(name);
}
// 输出: seven

我们先来回忆一下python的作用域(如果不会python可以跳过,不影响后面阅读):

 # 情况一:
def func():
if 1 == 1:
name = 'alex'
print(name)
func()
# 成功 # 情况二:
def func():
if 1 == 1:
name = 'alex'
print(name) func()
print(name)
# // 报错

再来看看JavaScript采用函数作用域:

 function Main(){
var innerValue = 'seven';
} Main(); console.log(innerValue); // 报错:Uncaught ReferenceError: innerValue is not defined

  在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量。console.log(innerValue)访问函数Main()中的变量肯定是不行的。

第二句话:JavaScript函数的作用域在函数未被调用之前,已经创建

  在JavaScript中如果不创建(声明)变量,直接去使用,则报错:

 console.log(x);
VM199:1 Uncaught ReferenceError: x is not defined(…)

  JavaScript中如果创建值而不赋值,则该值为 undefined,如:

 var num;
console.log(num); //undefined

了解了这个看看下面这个函数:

 function func(){
if(1==1){
var name = 'alex';
}
console.log(name);
}

  在浏览器中直接输入这个函数会得到undefined,而不是报错,就说明变量name在函数调用之前就创建(声明)了,但没有被赋值。

第三句话:函数的作用域存在作用域链,并且也是在被调用之前创建

  1 <script>
2 x = "alex";
3 function func() {
4 var x = "eric";
5 function inner() {
6 var x = "tony";
7 console.log(x);
8 }
9 inner();
10 }
11 func();
12 </script>

输出结果是tony。

如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量时候就会出现顺序,对于上述实例:

当执行console.log(xo)时,其寻找顺序为根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没找到抛出异常。

练习题1:

 x = "alex";
function func() {
var x = "eric";
function inner() {
console.log(x);
}
return inner;
}
var res = func();
res();

结果:eric

上述代码,在函数被调用之前作用域链已经存在:

  • 全局作用域 -> func函数作用域 -> inner函数作用域

当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。

练习题2:

 x = "alex";
function func() {
var x = "eric";
function inner() {
console.log(x);
}
var x = 'tony';
return inner;
}
var res = func();
res();

结果:tony

第四句话: 函数内局部变量 声明提前

 function func(){
console.log(xo);
var xo = 'alex';
} func();
// undefined

上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

四句话总结JavaScript作用域的更多相关文章

  1. 四句话表明JSON格式定义

    (1):并列的数据之间使用逗号(",")分割: (2):键值对的映射用冒号(":")表示: (3):并列数据的集合(数组)用方括号("[]" ...

  2. 五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  3. 【】五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  4. 五句话搞定JavaScript作用域(ES5)

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  5. 五句话搞定JavaScript作用域【转】

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  6. 160630、五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕.   一.“JavaScript中无块级作用域” 在Java或C# ...

  7. 【Python之路】特别篇--五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  8. JS作用域就这么几句话

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  9. 5句话搞定ES5作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

随机推荐

  1. shell 中函数放回字符串问题

    shell 中函数放回字符串问题 shell 中不可以直接 return 字符串 ,可以return 数字.如果要return 字符串 改为 echo "hello world" ...

  2. jfinal获取当前访问路径和端口号

    public void generateSingleLicense() throws Exception { System.out.println(getRequest().getRequestURL ...

  3. 通过ftp模拟网盘

    package com.xiaomo.ftp.down_upload; import java.io.IOException; import java.util.ArrayList; import j ...

  4. 真相:中国版BBB用USB连电脑没有盘符的根本原因分析

    很多网友在问:为什么中国版的装完驱动插上板子没有显示端口号和69M的盘符??楼主发现,在开机启动的时候,加载g_multi模块时出现错误提示 invalid argument.         Emb ...

  5. 解锁Dagger2使用姿势(二) 之带你理解@Scope

    关于Dagger2使用的基础如果你还不了解,可以参考我的上一篇文章解锁Dagger2使用姿势(一),这有助于你理解本篇文章. OK,我们在上篇文章介绍另外Dagger2使用过程中四个基本的注解,分别是 ...

  6. 深入理解计算机系统第二版习题解答CSAPP 2.9

    基于三元色R(红)G(绿)B(蓝)关闭(0)和打开(1),能够创建8种不同的颜色,如下: R G B 颜色 R G B 颜色 0 0 0 黑色 1 0 0 红色 0 0 1 蓝色 1 0 1 红紫色 ...

  7. Hessian

    一.远程通讯协议的基本原理 网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http . tcp . udp 等等, http . ...

  8. 【转】ArrayList的toArray

    [转]ArrayList的toArray ArrayList提供了一个将List转为数组的一个非常方便的方法toArray.toArray有两个重载的方法: 1.list.toArray(); 2.l ...

  9. android多国语言文件夹

    android多国语言文件夹文件汇总如下:(有些语言的书写顺序可能跟中文是相反的) 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中文(香港):values-zh ...

  10. WKWebView无法(通过URL schemes)跳转到其他App

    Custom scheme URL 在WKWebView中默认是不支持的 (但Safari可以). 我们可以通过NSError来进行一些处理从而使得程序可以正常跳转: func webView(web ...