- 每个执行环境(execution context )都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。
- 某个执行环境中的所有代码执行完毕之后,该环境被销毁,保存在其中的变量和函数也随之销毁
- 每个函数都有自己的执行环境当执行流进入一个函数时,函数的执行环境就会被推入一个环境栈中,而在函数执行完毕之后栈将其执行环境弹出,把控制权交给之前的执行环境。
- 当代码在一个环境中执行,会创建变量对象的一个作用域链(scope chain).如果执行环境是函数,则将其活动对象(activation object)作为变量对象。活动对象最开始只包含一个变量,即arguments对象。作用域链的下一个变量对象来自包含环境,而再下一个变量对象来自下一个包含环境,一直延续到全局执行环境。
- 标识符解析是沿着作用域链一级一级搜索标志符的过程,从作用域链的前端开始,然后向后回朔,直到找到标识符为止。
- 没有块级作用域。使用var声明的变量会自动添加到最接近的环境中,在函数内部,最接近的环境就是函数的局部环境。如果没有使用var 声明,该变量会自动添加到全局环境中。
- 函数声明有一个重要特性--函数声明提升(function declaration hoisting),即在执行代码之前先读取函数声明。
person() function person() { alert("person"); } teacher() var teacher = function() { //匿名函数(anonymous function) alert("teacher"); }
- 闭包是指有权访问另一个函数作用域中的变量的啊函数。创建闭包的常见方式就是在一个函数内部创建另一个函数。
-
function animal(age){ var age = age; return age; }
第一次调用animal()时创建一个包含this、arguments、age的活动对象。全局环境的变量对象包括this、animal。在创建animal()函数的时候会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。当调用animal()函数时,会创建一个执行环境,然后通过复制函数的[[Scope]]属性中对象构建起执行环境的作用域链。此后,又有一个活动对象被创建并推入执行环境作用域链的前端。 -
function animal(age) { return function() { document.write("dog age is: " + age); } } var dog = animal(12); dog();
当匿名函数从animal()返回后,他的作用域链被初始化为包含animal()活动对象和全局变量对象。这样匿名函数就可以访问在animal()所定义的变量。更为重要的是,animal()执行完毕之后其活动对象也不会销毁,因为匿名函数的作用域链仍然引用这个活动能够对象。换句话说,animal()执行完成之后其作用域链会被销毁,但是活动对象仍然保存在内存中;知道匿名函数被销毁,animal()活动对象才会被销毁,eg.dog = null; //解除对匿名函数的引用,则animal()函数的活动对象从内存中释放
-
function animal() { var result = new Array(); for(var i = 0;i<5;i++){ result[i]=function(num){ return function(){ document.write("这是第几个呢?: " + num) ; document.write("<br>"); } }(i) } return result; } var result = animal(); for(var i=0;i<result.length;i++){ result[i](); }
-
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。不过匿名函数的执行环境具有全局性,因此其this对象通常指向window.
var name = "window object"; var obj = { name : "obj object", getName : function() { return function() { document.write("getName: " + this.name); } } } obj.getName()();
-
模仿块级作用域
function animal() { (function() { alert(); var i = 12; })() alert(i); //i是没有定义的,报错 } animal();
-
任何函数中定义的变量都是私有变量,包括函数的参数、局部变量和在函数内部定义的其他函数。
function Animal() { var age =22; function addAge(){ console.log("addAge this : ",this); //这个this为window age++; } this.publicMethod = function(){ console.log("publicMethod this : ",this); //这个this为Animal addAge(); alert(age); return this; } } var animal = new Animal(); animal.publicMethod().publicMethod();
-
静态私有变量
(function() { document.write("匿名函数被调用"); var name = "" Person = function(value) { name = value; } Pserson.prototype.getName = function() { document.write("name: " + name); } })(); var p1 = new Person("zhang"); p1.getName(); var p2 = new Person("zhao"); p1.getName();