函数定义
- 内存中封装一项任务的步骤清单代码段的存储空间,再起一个名字。
- 函数其实是引用类型的对象。
- 函数名仅是引用函数对象的变量。
执行过程
定义时
- 仅创建函数对象,封装步骤清单代码段的对象。
- 不读取函数内容。
调用前
1.在ECS中为本次调用压入新的EC.
2.创建AO,将引用保存在EC中。
3.预读所有局部变量保存在AO中。
注:
- ECS——Execution Content Stack:保存所有函数调用的执行环境的栈结构。
- EC——Execution Content:保存本次函数调用的执行环境的栈元素。
- AO——Activation Object:实际存储本次函数调用的所有局部变量的对象。(继承自window)
调用时
1.只要AO中有,就不用window中的;如果AO中没有才去window中获取。
2.依次读取每行代码,执行。
调用后
1.EC先出栈。
2.AO释放,所有局部变量不复存在。此时如果再使用局部变量会报错!
创建函数——三种方法
1.声明
声明提前:
在正式执行程序前,都会先预读所有var声明的变量和function声明的函数,集中到当前作用域的顶部集中声明。
赋值留在原地
function 函数名(参数列表){
函数体;
return 返回值;
}
/*例:*/
function compare(a,b){
var c=a-b;
return c;
}
只有声明方式创建的函数才能被hoist(声明提前)。
2.函数直接量
var 函数名=function(参数列表){
函数体;
return 返回值;
}
/*例:*/
var compare=function(a,b){
var c=a-b;
return c;
}
3.new Function
var 函数名 = new Function("参数1","参数2",...,"函数体;return 返回值");
/*例:*/
var compare=new Function{"a","b","return a-b"};
使用字符串形式的函数体,需要借助eval才能转为代码,效率低。
变量作用域
- 一个变量的可用范围。
- 其实就是AO和window,统称VO(变量对象——专门保存各种变量的对象)。
全局作用域
- 存在window中的变量——全局变量。
- 任意位置都可以访问。
- 可重复利用。
- 问题:容易被污染,即很容易被篡改。
函数作用域
- 在函数内声明的变量和参数变量——局部变量。
- 只在函数调用时创建。
- 调用完毕,随AO释放。
- 问题:不可重用,只能在函数内访问。
var n=10;
function fun(){
var m=100;
consoel.log(n);
console.log(m);
}
fun();//10 100
console.log(n);//10
consoel.log(m);//报错
按值传递
两变量间赋值,或将变量传入函数中时,都是将原来变量中的值复制一份给对方。
如果是原始类型的值
修改对方变量,不影响原变量。
如果是引用类型的对象
通过对方变量修改对象,会影响原变量;因为两个变量使用同一地址,引用 了同一个对象
代码1:
var n=10;
function fun(){
var m=n;
m++;
console.log(n);
console.log(m);
}
fun();//10 11
console.log(n);//10
console.log(m);//报错
代码2:
var n=10;
function fun(){
var m=n;
n++;
console.log(n);
console.log(m);
}
fun();//11 10
console.log(n);//11
console.log(m);//报错