添加到桌面   加入收藏

通过函数作用域和块级作用域看javascript的作用域

08-05 11:06 来源:未知 编辑:admin  人气:   点评:评论一下 刷新: 刷新文章

在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量界说并能够被访问到的范围。也就是说如果一个变量界说在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量界说在函数内部,那么就只能在函数内部访问到这个变量。

全局作用域只要页面没关闭就会一直存在,而函数作用域只有在函数执行的时候才存在,执行完就销毁。且每次执行函数都会创建一个新的作用域。

那么什么是作用域链呢?
在了解作用域链之前,我们先了解一个执行期上下文的观点。

执行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象(即AO或GO),一个执行期上下文界说了一个函数的执行环境,函数每次执行时对应的执行期上下文都是唯一无二的,所以每次调用一个函数都会创建一个新的执行期上下文,当函数执行完毕,所发生的执行期上下文被销毁。

作用域链就是函数中[[scope]]属性所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

作用域链更像是一种包罗的关系。好比说函数A内部界说了一个函数B,所以B的界说是依赖于A的,也就是说B在A的内部,那么B中就可以访问A的中的变量和要领。这种一层一层向上依赖的关系就构成了作用域链。

为了更好理解,我们直接看例子。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {
  var num1 = 10;
  console.log(num);
 };
 return fn3;
}
var fn4 = fn2();

在上个例子我们知道,fn2执行的时候返回fn3,发生了闭包。但是一个函数执行然后返回另一个函数都会发生闭包嘛?我们来看一下。

var name = 'xiaoyu';
function fn1() {};
function fn2() {
 var num = 10;
 function fn3() {//fn3函数没有依赖fn2函数内的变量
  var num1 = 10;
  console.log(num1);
 };
 return fn3;
}
var fn4 = fn2();

了解了作用域链之后,我们来看一个小例子,巩固一下。

var age = 10;
var obj = {
 age: 12,
 test: function() {
  console.log(age);
  console.log(obj.age);
  console.log(this.age);
 }
}
obj.test();

console.log(this.age)打印出12不难理解,但是为什么console.log(age)不也应该打印出12嘛。

我们说test执行时首先会在自己的作用域内查看有没有age变量,然后再沿着作用域链往上到全局作用域查找age变量,全局作用域下有age变量和data变量。所以console.log(age)打印出的10,如果要打印出12则需要访问obj.age。

ES6的块级作用域

在ES6之后,通过let和const引入了块级作用域。即通过let和const声明的变量只在声明所在的块级作用域内有效,而且let声明的变量虽然属于全局变量,但不再属于全局对象window。

我们通过一段代码来看一下引入块级作用域后,函数的作用域链的变化。

var age = 10;
let obj = {
 age: 12,
 test: function() {
   console.log(age);
   console.log(obj.age);
   console.log(this.age);
 }
}
obj.test();

您可能感兴趣的文章:

  • JavaScript执行环境及作用域链实例分析
  • 详解js的作用域、预解析机制
  • Javascript中的作用域及块级作用域
  • 浅谈js的解析顺序 作用域 严格模式
  • javascript 作用于作用域链的详解
  • 浅谈JavaScript作用域和闭包
  • javascript基础进阶_深入剖析执行环境及作用域链
  • JavaScript变量类型以及变量作用域详解
[提醒] 转载请保留( 飞猪云教程)文章链接,谢谢!对本文有疑问欢迎留言讨论 ( 我有话说)!
元芳,把你的犀利的看法写到这里可好?
  • 全部评论(0
    还没有评论,快来抢沙发吧!