js预编译
Posted d-laowu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js预编译相关的知识,希望对你有一定的参考价值。
将代码封装成函数的形式,可以减少代码的耦合(编程追求的是高内聚,弱耦合)
函数声明:
function sayhello(){
console.log(‘hello world‘)
}
函数表达式:(一般指的匿名函数表达式)
命名函数表达式:
var say = function sayhello(){
console.log("hello world")
}
匿名函数表达式:
var say1 = function(){
console.log("hello world")
}
命名函数表达式与匿名函数表达式唯一的区别:
console.log(say.name) ==> sayhello
console.log(say1.name) ==> say1
在ES5以前,作用域分为两种:全局作用域,局部作用域(也称函数作用域)
1.任何变量,如果变量未经过声明就赋值,此变量就归全局所有
2.arguments 类数组对象,记录的是所有的实参集合
每个function都会生成一个自己作用域
var a = 123;
function fun(){
var c = 234;
console.log(a,c) ==>都有返回值(在局部作用域中可以访问全局作用域的变量)
}
fun();
console.log(a) ==>a为全局变量,有返回值
console.log(c) ==>c为局部变量,全局作用域中没有,会报错(全局作用域中不能访问局部作用域的变量)
注意console.log(name) 不会报错,name是window的自带属性
函数执行前的流程,在执行函数fun()前,浏览器会做3件事:
1.语法分析 检测代码有没有低级错误(有会报错)
2.预编译
3.根据编译好的来逐行执行
预编译:
1.函数运行前的一瞬间,会生成一个AO对象(Active Object),简称AO,执行期上下文
2.分析参数,形参作为AO对象的属性名,实参作为AO对象的属性值
3.分析变量声明,变量名为属性名,值为undefined,如果遇到同名的不做任何改变
4.分析函数声明,函数名为属性名,函数值为函数体,如果遇到同名的直接覆盖
函数执行一次,就会产生一次预编译的过程,预编译是执行前的过程
实例:
function fun(a){
var b = 123;
function c(){
var d = 234;
}
}
fun(6);
预编译:
1.在函数fun运行前的一瞬间,生成一个AO对象(为函数c的GO)
fun.AO = {};
2.分析参数(假如没有,略过)
fun.AO ={
a : 6
}
3.分析变量(假如没有,略过)
fun.AO ={
a : 6,
b : undefined
}
4.分析函数声明(假如没有,略过),最终:
fun.AO ={
a : 6,
b : undefined,
c : function(){
var d = 234;
}
}
然后根据AO对象执行函数,当函数执行完成后,AO对象会自动销毁
作用域:
全局作用域 --相对的
函数作用域 --只要出现function就会产生自己的作用域
函数本身也是一个对象
fn.name
fn.length
fn.prototype
fn.[[scope]] 看不到的属性,给系统内部去读 简单一点理解:放的就是GO和AO
把[[scope]]的集合构成链状的形式,就形成作用域链,本质就是一个javascript对象
执行期上下文:当函数执行的时候,会创建一个执行期上下文的内部对象,存储了定义好的变量,函数...
执行期上下文属于独一无二的,每当你函数调用一次,就会产生新的执行期上下文,当你的函数运行完成,执行期上下文就会被销毁
闭包:
function a(){
var num = 100;
function b(){
num ++;
console.log(num);
}
return b;
}
var demo = a();
demo() 》 101
demo() 》 102
b 执行 --> demo() b.[[scope]] 0 : b.AO num++
1 : a.AO
2 : GO
坏处: 作用域链得不到释放,造成内存的泄露
好处: 累加器
做缓存
封装
模块化开发,避免全局污染
只能通过指定的接口去访问或者操作内部变量
闭包做缓存
function test(){
var num = 100;
function a(){
num ++;
console.log(num)
}
function b(){
num --;
console.log(num)
}
return [a,b]
}
var arr = test();
arr[0]();
arr[1]();
以上是关于js预编译的主要内容,如果未能解决你的问题,请参考以下文章