WEB学习进阶之路三
javascript的作用域(scope)
javascript中有三种作用域类型
全局作用域
局部作用域
块级作用域
javascript的作用域决定了变量的可访问性,也就是可见性。举个简单的例子看看
<script> var outVar; //此变量全局可访问,也就是全局作用 function foo() { var inVar; //此变量只有foo函数内部可以访问,也就是局部作用 } </script>
全局作用域
就是声明在脚本最外层的变量,例如上述代码中的outVar变量,在全局的任何一出都可以引用它。
局部作用域
就是声明在局部区域的变量,比如上述代码中的inVar变量,只能在函数foo中访问。
变量自动全局
function foo(){x = 10;} foo(); console.log(x); // 10
和下面的结果一样,说明此处的变量自动被提升为全局变量
var x; function foo(){x = 10;} foo(); console.log(x); // 10
注意此处有坑,如果采用这种方式,有可能就会污染全局变量(和其他全局变量重名),导致代码异常,代码编写时一定要有好的习惯,或者采用"use strict"模式避免这个问题。
变量有效期
有效期起始与变量在被创建时,局部变量在函数结束时被销毁,全局变量在页面被关闭或者跳转后被销毁
变量的提升(Hoisting)
提升的作用是,将变量的声明提升到当前脚本或者当前函数的顶部的行为,举个例子
x = 'hello china'; console.log(x); // hello china var x;
注意,变量的初始化不会被提升,举个例子
var x; console.log(x); // undefined x = 'hello china';
使用let或者const定义的变量也不会被提升
块级作用域
let
var a='hello china'; for (let a=0;a<10;a++){ }; console.log(a); // hello china
注意上面的let,和下面的var对比下
var a='hello china'; for (var a=0;a<10;a++){ }; console.log(a); // 10
注意在一个作用域内,不能使用let重新定义var 变量
同样的反过来也是不允许的
注意之前提到过的知识点,变量提升,如果用let会怎么样呢?
说明,通过let定义的不能提升变量
const
const定义的变量和let作用范围是一样的,不同的是,const定义的变量必须在声明时赋值,注意const定义的是对常量的引用,而不是常量的值。
const PI = 3.14
如果先声明后赋值则报错
声明后修改
但是const定义的属性可以被修改
作用域链
通俗的讲,就是内部函数可以访问外部函数或者变量的过程,就是通过作用域链查找的
在调用变量时,先在本级查找,没有的就向上级(父级)查找,一次类推,一直到window级别,如果还没找到,就表明改变量未定义,报错undefined。
这里需要注意的是,变量的定义是在编写代码结构时就已经定好的,换句话说,就是创建函数的那个作用域中的范围,下面举个列子说明下
看明白了把,这里的x是foo函数定义的级别的值,不是调用的地方级别的值。
为什么呢,这里就要说到javascript的执行方式了,javascript是解释型语言,分为解释和执行两个阶段,
解释阶段
词法分析
语法分析
作用域规则确定
执行阶段
创建执行上下文
执行代码
垃圾回收
这里就明白了,作用域是在代码结构编写是就已经定好,不能再变了。
这里在解释下执行上下文,对于执行上下文最明显的就是this指针,他可以在调用的地方,随时改变。
- 点赞
- 收藏
- 关注作者
评论(0)