JavaScript函数调用时的作用域链和调用对象是如何形成的及与闭包的关系

1、javascript解析器启动时就会初始化建立一个全局对象global object,这个全局对象就拥有了一些预定义的全局变量和全局方法,如Infinity, parseInt, Math,所有程序中定义的全局变量都是这个全局对象的属性。在客户端javascript中,Window就是这个javascript的全局对象。
2、当javascript调用一个function时,会生成一个对象,称之为call object(调用对象),function中的局部变量和function的参数都成为这个call object的属性,以免覆写同名的全局变量。调用对象: ECMAScript规范术语称之为activation object(活动对象)。
3、javascript解析器每次执行function时,都会为此function创建一个execution context执行环境,在此function执行环境中最重要的一点就是function的作用域链scope chain,这是一个对象链,由全局对象和调用对象构成,对象链具体构成过程见下面说明。
4、当javascript查询变量x的值时,就会检查此作用域链中第一个对象,可能是调用对象或者是全局对象,如果对象中有定义此x属性,则返回值,不然检查作用域链中的下一个对象是否定义x属性,在作用域链中没有找到,最后返回undefined。
5、当javascript调用一个function时,它会先将此function定义时的作用域作为其作用域链,然后创建一个调用对象,置于作用域链的顶部,function的参数及内部var声明的所有局部变量都会成为此调用对象的属性。
6、this关键词指向方法的调用者,而不是以调用对象的属性存在,同一个方法中的this在不同的function调用中,可能指向不同的对象。
7、The Call Object as a Namespace
(function() {
// 在方法体内用var声明的所有局部变量,都是以方法调用时创建的调用对象的属性形式存在。
// 这样就避免与全局变量发生命名冲突。
})();
8、javascript中所有的function都是一个闭包,但只有当一个嵌套函数被导出到它所定义的作用域外时,这种闭包才强大。如果理解了闭包,就会理解function调用时的作用域链和调用对象,才能真正掌握javascript。
9、当一个嵌套函数的引用被保存到一个全局变量或者另外一个对象的属性时,在这种情况下,此嵌套函数有一个外部引用,并且在其外围调用函数的调用对象中有一个属性指向此嵌套函数。因为有其他对象引用此嵌套函数,所以在外围函数被调用一次后,其创建的调用对象会继续存在,并不会被垃圾回收器回收,其函数参数和局部变量都会在这个调用对象中得以维持,javascript代码任何形式都不能直接访问此对象,但是此调用对象是嵌套函数被调用时创建的作用域链中的一部分,可以被嵌套函数访问并修改。

<script>
  /*var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){return function(){return this.name;};}
  };
  alert(object.getNameFunc()());
*/
  
  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){var that = this;alert(this.name);return function(){return that.name;};}
  };
  alert(object.getNameFunc()());
</script>

 

你可能感兴趣的:(JavaScript)