一、js预编译
(一)在函数中的预编译的步骤
var a = 123;
function a() {}
var b = function() {}
function d() {}
}
fn(1)
- 创建AO对象 (Activation Object) (执行期上下文),AO对象就是作用域 AO:{ }
- 找形参和变量声明,将变量和形参名作为AO对象的属性名, 值为undefined AO:{ a : undefined, b : undefined }
3.将实参值和形参相统一 AO:{ a : 1, b : undefined }
4.在函数体里面找函数声明,将函数声明的名(函数名)作为AO对象的属性名挂起来, 函数体赋予属性值 AO:{ a : function a() {}, b : undefined, d : function d() {} }
(二)预编译的作用
与编译发生在函数执行的前一刻 预编译的目的就是为了创建AO对象,等待函数执行的时候去使用。
(三)在全局中的预编译
全局中的预编译与函数中的预编译大致上是一样的,全局创建的上下文对象是GO(Global Object) 并且全局预编译不走第三步,window就是GO。先生成GO在生成AO
二、作用域精解
[[scope]]:每个js函数都是一个对象,对象中有些属性我们可以访问,但是有些不可以, 这些属性仅供js引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域 其中存储了运行时上下文的集合。
运行期上下文:函数执行时,会创建一个称为“执行期上下文”的内部对象。 一个执行期上下文,定义了一个函数执行时的环境,函数每次执行时对应 的执行上下文都是独一无二的,所以多次调用同一个函数会导致创建多个 执行期上下文,当函数执行完毕,它所产生的执行期上下文就自动销毁了。
三、立即执行函数
立即执行函数,执行完后函数所占空间就会被立即释放。 (function(){
}())
四、闭包
但凡内部的函数被保存到了外部一定生成了闭包。闭包会导致作用域 链不释放,造成内存泄露。
#五、this关键字
(一) 全局对象中的this
- 在全局环境下,this指向全局对象,在浏览器中为window对象,无论是否在严格模式 下,this都是执行全局对象。 eg:
var x = 1;
console.log(this.x) //1
console.log(this === window) //true
- 如果函数是在全局环境中被调用,在非严格模式下,函数中的this指向全局对象。 如果在严格模式下,this是undefined。 eg:
var x = 1;
function demo() {
console.log(this.x);
}
demo();
"use strict"
var y = 1;
function foo() {
console.log(this.y);
}
foo(); //Uncaught TypeError: Cannot read property 'y' of undefined