作用域 :是一个函数在执行时期的执行环境。
基本概念:每一个JavaScript函数都是一个对象,对象中有些属性我们可以访问,有些我们不可以访问,这些属性仅供JavaScript引擎存取,[[scope]]就是其中的一个。
[[scope]] : 指的就是我们所说的作用域,其中存储了执行期上下文的集合
作用域链 : [[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链接叫做作用域链,它就决定了哪些数据可以被函数访问
运行期上下文 : 当函数执行时,会创建一个称为执行期上下文的内部对象(AO——Action Object)。一个执行期上下文定义了一个函数执行的环境,函数每次执行时对应的执行环境都是独一无二的,它所产生的执行上下文被销毁。
查找变量 : 从作用域的顶端依次向下查找。
立即执行函数
立即执行函数在执行一次后就立即销毁,适合做一些初始化工作
写法 :
(function(){})()
(function(){}())//W3C推荐使用
函数声明:
funcion fun(){
console.log(123);
}()//会报错
函数表达式:只有表达式才可以被执行符号执行
var t = function(){
console.log(123);
}()//输出123 这是一个表达式
(function(){
console.log(123);
}())//输出 123
加上 +-! 可以变成函数表达式
**阿里面试题**
function fun(a,b,c){
console.log(a+b+c);
}(1,2,3)//不会报错 也不会执行
闭包
产生原因:
- 产生闭包的原因是由作用域链引起的
- 函数嵌套函数,被嵌套的函数就可以称为闭包
作用:
- 子函数可以使用父函数的变量(可以读取自身函数外部的变量——>沿着作用域链寻找 )
让变量始终保存在内存中,避免自动垃圾回收
闭包练习
练习一
<script type="text/javascript">
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
return function() { //匿名函数具有全局性 因此this指向全局
return this.name;
};
}
};
console.log(object.getNameFunc()()); //result:The Window
</script>
//javascript高级程序设计会给出的解释是:this对象是在运行时基于函数的执行环境
绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那
个对象。不过,匿名函数具有全局性,因此this对象同常指向window
练习二
<script type="text/javascript">
function test(){
var arr = [];
for(var i = 0;i < 10 ;i++){
arr[i] = function(){
console.log(i)
return i;
}
}
return arr;
}
var arr1 = test()
console.log(arr1) //函数执行后会有返回值 返回值是数组arr
for(var j = 0 ;j < arr1.length ;j++){
arr1[j]();
}
// 结果是打印出来10个10
//如何让它打印出来0-9
function test(){
var arr = [];
for(var i = 0;i < 10 ;i++){
arr[i] = function(){
console.log(i)
return i;
}();//函数表达式 让它立即执行
}
return arr;
}
test()
</script>
//输出结果0-9
再来看一个简单的例子
<script type="text/javacript>{
function fun() {
var s = 0;
console.log(s);
}
fun() //输出0
var s = 3 ;
console.log(s) //输出3
</script>
<script type="text/javacript>{
function fun() {
s = 0; //不用var声明 修改相当于把全局中的s重新赋值为0 所以输出的结果s就是0
console.log(s);
}
fun() //输出0
var s = 3 ; //相当于全局中的var
console.log(s) //输出0
</script>