javascript闭包
闭包是什么
闭包的产生
我觉得是因为闭包函数的作用域链中保存着包裹函数的活动对象,正因保留着引用,导致包裹函数不会被垃圾回收
特点
- 闭包会引用包含函数的整个活动对象
- 是个函数
闭包的作用
- 模拟私有方法
作用域链
作用域链和闭包脱不了干系,作用域链部分可以查看javascript作用域
我觉得是因为闭包函数的作用域链中保存着包裹函数的活动对象,正因保留着引用,导致包裹函数不会被垃圾回收
作用域链和闭包脱不了干系,作用域链部分可以查看javascript作用域
暂时只是大概读了一遍,先记下来
自上而下
前四层构成TCP/IP协议族,之所以分层,我觉得可以理解为像前端的模块化,易于管理,改动。实际上设计也变得简单,各层只需考虑自己分内的事
应用层决定了向用户提供应用服务时通信的活动。
包含FTP,DNS,HTTP
传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。
包含TCP,UDP(用户数据报协议)
网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。
IP
用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
发送端首先发送一个带 SYN 标志的数据包给对方。接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。最后,发送端再回传一个带 ACK 标志的数据包,代表“握手”结束。 若在握手过程中某个阶段莫名中断,TCP 协议会再次以相同的顺序发送相同的数据包。
生成针对目标服务器的HTTP请求报文
浏览器两个引擎
渲染引擎
常称为浏览器的内核,webkit,gecko,persto(opera)
js引擎
调试工具中报如上的错误,查阅资料得知是chrome某个插件报的错,自己一一验证,发祥是迅雷下载插件这个毒瘤,禁用可消除如上的报错
图解http
整理一些angular相关的问题,多了再整理
脏检查机制。
双向数据绑定是 AngularJS 的核心机制之一。当 view 中有任何数据变化时,会更新到 model ,当 model 中数据有变化时,view 也会同步更新,显然,这需要一个监控。
原理就是,Angular 在 scope 模型上设置了一个 监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时,$digest 循环就会触发,遍历所有的 $watch,最后更新 dom。
举个栗子
<button ng-click="val=val+1">increase 1</button>
click 时会产生一次更新的操作(至少触发两次 $digest 循环)
按下按钮
浏览器接收到一个事件,进入到 angular context
$digest 循环开始执行,查询每个 $watch 是否变化
由于监视 $scope.val 的 $watch 报告了变化,因此强制再执行一次 $digest 循环
新的 $digest 循环未检测到变化
浏览器拿回控制器,更新 $scope.val 新值对应的 dom
$digest 循环的上限是 10 次(超过 10次后抛出一个异常,防止无限循环)。
自己感觉吧,绑定在$scope上的变量都会被监听,有变化时会刷新整个$scope上的队列。
执行环境很重要,执行环境定义了变量或函数有权访问的其他数据(难道指的就是初始化的作用域链?),决定论它们各自的行为。每个执行环境都有一个与之关联的 变量对象(包含了环境中定义的所有变量和函数)(难道执行环境只包含了一个标识符指针列表?),虽然我们的代码无法访问这个对象,但解析器在数据处理时会在后台使用它
全局执行环境是最外围的执行环境,在Web浏览器中,全局执行环节被认为是window对象
每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中,在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
也就是说这个栈一直存在,和全局执行环境一样关闭网页时才被销毁
当代码在一个环境中执行时,会创建变量对象的一个 作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数有序的访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象,活动对象在开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
作用域链存放在哪
以上大部分来自js高程这本书,下面开始图解
//myScript.js
"use strict"
var a=1;
var b=2;
如图,开始时,创建全局执行环境并被推入执行环境栈
//myScript.js
"use strict"
var a=1;
var b=2;
function foo(){
var c=3;
var d=4;
console.log(c+d);
}
执行至function foo(){}也就是函数创建时,food的标识符(identifier)被加到当前(栗子中是全局变量对象)中,并且这个标识符引用了一个函数对象,函数对象中不仅包含了函数的源代码等还有[[scope]],[[Scope]]属性中保存了一条用来初始化作用域链,其指向就是当前的变量对象(全局变量对象)
注意此时并没创建函数相应的执行环境
//myScript.js
"use strict"
var a=1;
var b=2;
function foo(){
var c=3;
var d=4;
console.log(c+d);
};
foo();
执行至foo(),函数被调用,产生相应的执行环境,之后被推入执行环境栈顶,
此时产生的执行环境中的作用域链由之前函数定义时的[[scope]]而来,作用链的前端为foo的变量对象,由于这个环境是函数,创建活动对象并将其作为变量对象
调用foo()结束后,其执行环境会被弹出执行栈,
1.作用域链是本质上是一个指向变量对象的指针列表,它只是引用但不实际包含变量对象。
2.AO中包含了函数的形参、arguments对象、this对象、以及局部变量和内部函数的定义,然后AO会被推入作用域链的顶端。
感觉AO和VO里的内容差不多
当函数被调用时进入EC的产生阶段
javascript中的this接触很多,但一直是模模糊糊的,在这里整理下
与其他语言相比,函数的 this 关键字在JavaScript中的行为略有不同。它在严格模式和非严格模式之间也有一些区别。
读了廖雪峰老师的文章感觉文中所说的调用对象就是指执行环境,不知道可不可以这样理解
当一个函数被调用时,会创建一个 __执行环境(execution context)__及相应的作用域链,自动获取两个特殊变量:this和arguments,然后使用arguments和其他命名参数的值来初始化函数的 **活动对象(activation object)**,
(function(){}())立即执行函数
构造函数模式创建对象时,会经历以下4个步骤
this总是指向调用函数的那个对象,在运行时基于函数的执行环境绑定的
属于全局调用,this代表全局对象Global
function foo(){
console.log(this);
};
foo(); //Window
this指向调用的函数
this 指向当前实例对象
apply()和call()作为函数对象的方法,可以改变函数的执行环境(调用对象)
它们的第一个参数是个对象,即作为函数内的this。
function foo(){
console.log(this);
}
foo.call(1); //1
foo.call('a'); //a
foo.call(true); //true
foo.call({type:object}); //[object Object]
如上,他们的参数作为函数内的this输出
需要注意的是,传null或undefined时,将是JS执行环境的全局变量。浏览器中是window,其他环境,如node则是global。
fun.call(null); //window or global
fun.call(undefined); //window or global
apply()和call()唯一的区别是参数不一样,apply的第二个参数必须传入数组。
如
func1.call(this, arg1, arg2);
func1.apply(this, [arg1, arg2]);
js中函数的参数不固定,当参数是明确知道数量时,用 call,而不确定的时候,用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个 __类数组__来便利所有的参数。
上面说的this的指向很偏应用的,倒是像经验上的总结。具体还是要看规范的,这部分打算之后再好好写写
页面间的传值还是很常见的,在此记录下我接触过的angular1.X版本页面间传值的例子