面包屑之javascript声明期与执行期的故事

js中万物皆对象,特殊的对象(function类型)在声明和执行的时候会发生一些奇妙的事情,如下:

function a(){
    var id = 1;
    function b(){
        alert(++i);
    }
  return b;
}
var c = a();

  

上述代码,是在全局作用域中声明了一个a

以函数a从定义到执行的过程为例阐述这几个概念。

  1. 定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。
  2. 执行函数a的时候,a会进入相应的执行环境(excution context)
  3. 在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。
  4. 然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
  5. 下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
  6. 最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。(所以的b的作用域为   b的活动对象-->a的活动对象-->全局window对象)

再回到代码  var c = a();  这时候把a()的返回值b函数指向c,然后c很神奇的可以访问到a的内部私有属性i了,这就是神奇的闭包了。

由于函数具有被调用时创建封闭环境的特性,因此在某些情况这种特性又被称为“闭包”

闭包自我理解:

   闭包应该是个抽象的概念,大概就是指function在执行时会创建的一个封闭环境,而这个环境只有他的内部函数可以访问。

   换一种说法:内部函数只有通过闭包才能访问到外部作用域

 关于闭包回收,应该是和其他对象一样,在没有被引用的情况下才会被回收。(即当内部函数被外部引用,在外部引用存活的情况下,闭包不会被回收)。 

执行期还有一点需要补充的,就是new这个神奇的关键字。

当一个函数被普通的执行时,是这样的:

function a(){
  var id = 1;
   return id;
}

function b(){
  alert(hello);
}
var c = a();   //return 1;
var d = b();   //return underfined;
//如果有返回值得情况,则返回该返回值
//否则返回默认值underfined,   return; 也是返回underfined

  

当一个函数被特殊的执行时,是这样的:

function a(){
  this.id = 1;
}
a.prototype.name = "tianxia";
function b(){
  alert(hello);
  return;
}
var c = new a();   //return {id:1,name:"tianxia"};
var d = new b();   //return underfined;
//如果在一个函数前面带上new来调用该函数,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将被绑定到那个新对象上。
//默认返回该this对象,如果有返回值还是返回该返回值。

  

ps:好吧,又是记录了一些理论的东西,上文纯属一个小菜的个人理解,如果有问题,请多多指点哈。

时间: 2024-07-31 00:53:10

面包屑之javascript声明期与执行期的故事的相关文章

css制作面包屑导航

css2制作面包屑导航主要的原理就是利用绝对定位以及当元素的宽度和高度都为零时边框的挤压性质,效果图 代码: <ul>     <li>HTML<i></i></li>     <li><em></em>CSS<i></i></li>     <li><em></em>JavaScript<i></i></li

辛星和您一起用纯CSS美化面包屑导航

首先讲一下面包屑导航为什么叫做面包屑导航,它来自于一个童话故事,这个童话故事的名字也非常有特色,叫做"汉塞尔和格莱特",有一天他们去森林里游玩,但是走着走着发现迷路了,大家都知道,森林里都都是数,不管往哪边走,还是茫茫的一片树,于是他们在沿途走过的地方都撒下面包屑,他们利用这些面包屑帮助他们走出了森林,因此,面包屑导航的意思就是说我们去过哪些地方,以及我们如何回到我们之前的位置. 有时候我们特别需要面包屑导航,比如我们在某论坛或者某网上商城闲逛的时候,很容易被茫茫的帖子和众多的商品搞的

knpMenuBundle制作面包屑导航 左侧导航 碉堡了

最近做一个小项目,用的symfony3玩的. 之前一直深受别的框架影响.习惯把链接管理写在数据库里,这样方面操作. 但是今天按照以前的思路做下来别的都还正常但是做面包屑导航的时候就遇到问题了.于是找了一个knpmenubundle来重做了栏目  发现这样做真的好快.比以前做的快多了 首先按照symfony官网中使用教程来操作. 简单的东西直接按官网走就解决了. https://github.com/KnpLabs/KnpMenuBundle/blob/master/Resources/doc/i

ASP.NET MVC 在项目中使用面包屑导航

给框架添加一个面包屑导航 1.创建一个类 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SAS.Model.AdminCommon { public class BreadCrumbsModel { public BreadCrumbsModel() { BreadCrumbList = new List<BreadCrumbModel>(); }

vue 使用localstorage实现面包屑

mutation.js代码: changeRoute(state, val) { let routeList = state.routeList; let isFind = false; let findeIdex = 0; //菜单栏和下拉的二级菜单 if (val['type'] == 'header' || val['type'] == 'secondHeader') { routeList.length = 0; //顶级菜单清除缓存 localStorage.removeItem("r

CSS实现面包屑

面包屑在用户引导方面起到很大作用,可以清晰的为用户指示出其当前所在位置,以及访问到此的整个路径如何,另一方面,面包屑也可以将较长的表单分割成一步一步完成且互动性较强的任务式表单填写.可见其在网页中的重要性.但样式美观的面包屑包含一些形状,这在CSS3以前得靠图片等其他方式实现,现在有了CSS3之后,我们可以很方便的用CSS绘制出常见的面包屑. 下面的案例中涉及了三个内容,所以将其记录于此: 1. display:inline-block的间距文题(是由于我们格式化代码时换行导致) 2. bord

YII 面包屑制作

什么是面包屑? 类似于这样就是 实现步骤: 1. 视图定义变量 2. 在布局通过显示 视图中代码: <?php //定义面包屑变量 $this -> breadcrumbs = array( '用户中心'=>array('user/center'), '用户登录'=>array('user/login'), ); ?> 布局中代码:通过小物件来是实现 <!-- <当前位置=---首页-----注册----> <?php if(isset($this-&

如何删除帝国cms面包屑导航中首页链接的/index.html

前面一篇"帝国cms面包屑导航的首页链接锚文本改成关键字"中xmyanke有写到改首页链接的方法,但是感觉比较麻烦,这里就说说如何删除帝国cms面包屑导航中首页链接的/index.html,我们的首页一般都是***.com/结尾的,如果Breadcrumb的中首页链接变成***.com/index.html结尾的话,会造成有两个首页,分散权重.重复收录.(当然可以把index.html 301到不带index.html) 找到e/class/connect.php,搜索$file=$p

Bootstrap面包屑导航

Bootstrap中提供了面包屑导航的实现方法: 只需要引入bootstrap.css文件即可. 主要引用的样式有: .span6 .breadcrumb 实例代码如下: <!DOCTYPE html> <html> <meta charset="utf-8"> <head> <title>bootstrap面包屑导航</title> <link rel="stylesheet" type