在上一篇提到了JS有三种声明变量的方式,分别是var、const及let,var和const let最大区别就是范围(scope)的限制。所以在这一篇我们会详谈何谓范围链及他们的复写优先级。

范围Scope

我们先来看一个例子:

var globalVar = 'global';

function scopeFun(){

globalVar =“change in scopeFun”;

console.log(“1.”,globalVar);//1.change in scopeFun

var funVar = 'Im in fun';

console.log(“2.”,funVar);//2.Im in fun

}

scopeFun();

console.log(“3.”,globalVar);//3.change in scopeFun

console.log(“4.”,funVar);//funVar is not defined

在function中所声明的var在全局是没办法作呼叫的,但是在全局声明的在function中却可以用。

这边我们可以确定两件事情:

var是函数级作用域(function-level scope)由function的{}所区隔。

变量会由内往外寻找直到全局,我们称这行为为范围链(Scope Chain)。

那我们再来看ES6新增的let及const的范围:

let globalLet = true;

function scopeFun(){

if(globalLet){

let localLet =“local let”;

const localConst =“local const”;

console.log(localLet,localConst);

}

console.log(localLet,localConst);

}

scopeFun();

由这个例子我们可以得知:

let及const的是内存块作用域(Blocak-level scope)由{}所区隔。

提升(Hoisting)

在讲解变量复写优先级前,我们还需要先了解什么是Hoisting:

在执行代码前,JS会把函式声明放进內存里面,可以在代码声明该函式之前使用它。

function myName(name){

console.log(“my name is”+name);

}

myName(“John”);//my name is John

一般在撰写一个函式时候都会这样作,但我们前面有提到说可以在声明该函式之前使用它,所以我们也可以这样作:

myName(“John”);//my name is John

function myName(name){

console.log(“my name is”+name);

}

当然提升也适用于变量,但是跟函式就有很大的区别了。

如果我们在声明前就先给初始化的话,是可以正常使用的:

price = 10;

price +=1;

console.log(price);//11

var price = 20;

但是如果在声明后才初始化,则前面使用将会得到undefined:

console.log(price);//undefined

var price = 20;

这段代码可以理解成这样:

var price;

console.log(price);//undefined

var price = 20;

这边要注意的是,ES6提供的变量声明let及const是无法做到的,会回报错误:

console.log(price);//ReferenceError: price is not defined

let price= 20;

那如果我们用变量声明函式的话,会发生什么事情呢:

console.log(price);//undefined

price(20);//TypeError: price is not a function

var price = function(amount){

console.log(20*amount);

}

可以看到只有变量被提升到最上面且是undefined,所以无法当成函式使用。

总结:

var是函数级作用域(function-level scope)由function的{}所区隔。

let及const的是内存块作用域(Blocak-level scope)由{}所区隔。

变量会由内往外寻找直到全局,我们称这行为为范围链(Scope Chain)。

可以在声明该函式之前使用它,这行为称为提升(Hoisting)。

变量var也有提升,但如果使用时没有初始化将会得到undefined。

用var声明函式无法在之前使用,因为var提升是undefined。

参考资料:

https://developer.mozilla.org/zh-TW/docs/Glossary/Hoisting

https://ithelp.ithome.com.tw/articles/10198485

学习JS的心路历程-范围Scope和提升(Hoisting)的更多相关文章

  1. 学习JS的心路历程-声明

    变量 在程序中将一个值指定(assign)给一个符号式的容器(symbolic container),叫做一个变量(variable). 声明在JS中目前提供了三种声明方式: var 声明一个变量,可 ...

  2. 学习JS的心路历程-函式(一)

    前几天有间单提到该如何声明函式及在Hositing中会发生什么事,但是函式的奥妙不仅于此. 身为一个使用JS的工程师,我们一定要熟悉函式到比恋人还熟! 这几天将会把函式逐一扒开跟各位一起探讨其中的奥妙 ...

  3. 学习JS的心路历程-参数的传递(下)

    今天我们要来探讨JS到底是透过何种参数传递方式呢? 废话不多说,上示例!! 我们先声明原始型别和物件型别来看看两者是否会有不一样的差异: var myStr = 'Hola': var myObj = ...

  4. 学习JS的心路历程-参数传递方式(上)

    很多人认为JS的传递方式是值是Call by value, 物件及数组是Call by Reference.甚至还有人宣称其实JS是Call by sharing,那到底是哪一个呢? 这两天我们一一来 ...

  5. 学习JS的心路历程-类型

    前言 之前学JS时候都是靠着谷狗一路跌跌撞撞的学过来,从来没有去翻过MDN的文件,导致留了许多技术债给自己. 最近有幸遇到一位前辈并开始从头学JS,前辈表示学程序不看文件是想作死自己?于是我的第一份功 ...

  6. 学JS的心路历程-闭包closure

    闭包是是纯函式语言的一个特性,也是JS的一个关键性的特色,虽然不了解也能开发程序,但我们不是这种人对吧? 闭包不仅可以减少某些高阶功能的代码数量和复杂度,并且可以让我们做到原本无法做的复杂功能.听到这 ...

  7. 学JS的心路历程 -函式(三)this

    this是什么,取决于被呼叫的呼叫地点. 昨天有提到说,呼叫函式时候会传递隐含参数:arguments和this并讲解了arguments,今天我们就来探讨this吧! 什么是this 我们都会呼叫函 ...

  8. .net工程师学习vue的心路历程(一)

    实习一年后,想做一个属于自己的博客网站,准备用core api去搭建服务端接口,前端准备采用vue这样的一个框架.本身时一个服务端程序员,所以来学习记录一些vue的知识点,有什么不足的希望大家指正,谢 ...

  9. React+Immutable.js的心路历程

    这段时间做的项目开发中用的是React+Redux+ImmutableJs+Es6开发,总结了immutable.js的相关使用姿势: Immutable Data 顾名思义是指一旦被创造后,就不可以 ...

随机推荐

  1. 2014年第五届蓝桥杯JavaB组省赛试题解析

    题目及解析如下: 题目大致介绍: 第一题到第三题以及第六题是结果填空,方法不限只要得到最后结果就行 第四题和第五题是代码填空题,主要考察算法基本功和编程基本功 第七题到第十题是编程题,要求编程解决问题 ...

  2. Javascript强制转换

    Javascript强制转换 Javascript强制转换强制转换一共有五种转换方式,各有各的用处,希望大家在实际的使用中灵活运用,不要死板. <!DOCTYPE html> <ht ...

  3. JSP 静态文件路径配置

    在JSP中,往往需要引入一些静态文件. 例如这样引用. 往往因为目录结构的问题,不知道是用点还是 .../ ./ ../表示相对当前路径的上一级目录:./表示相对当前的路径: 这里有个快捷的办法. l ...

  4. 《算法导论》——MaximumSubArray

    今天我们讨论的算法是最大子数组问题. 首先我定义了一个类用来保存最大子数组的开始位置索引.结束位置索引和该数组的和.代码如下: class MaximumSubArray { private: int ...

  5. pl/sql学习笔记---马士兵教程38-48

    Procedure Language/Structure query Language 一.关于语言学习 1.数据类型 2.语法   通过例子来学习很快就能明白 set serverputout on ...

  6. Python基础3 函数、递归、内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...

  7. kong API gateway

    参考:https://www.cnblogs.com/chenjinxi/p/8724564.html 一.简介 Kong,是由Mashape公司开源的,基于Nginx的API gateway. 二. ...

  8. 关于visual studio code在win10系统上安装后会报扩展宿主意外终止的解决方法

    我的电脑的地址 C:\Users\Administrator.SC-201810160958\AppData\Local\Programs\Microsoft VS Code\resources\ap ...

  9. Linux 指令(一)文件/目录操作

    1. 创建目录 mkdir 格式 mkdir [OPTION]... DIRECTORY... 选项 -p 递归创建 -v 创建时提示 例: root@ubuntu:/home/eko/x# mkdi ...

  10. STM32F103C8开发板原理图和管脚图