1、javascript解析器启动时就会初始化建立一个全局对象global object,这个全局对象就 拥有了一些预定义的全局变量和全局方法,如Infinity, parseInt, Math,所有程序中定义的全局变量都是这个全局对象的属性。在客户端javascript中,Window就是这个javascript的全局对象。
2、当javascript执行一个function时,会生成一个对象,称之为call object,function中的局部变量和function的参数都成为这个call object的属性,以免覆写同名的全局变量。
3、javascript解析器每次执行function时,都会为此function创建一个execution context执行环境,在此function执行环境中最重要的一点就是function的作用域链scope chain,这是一个对象链,由全局对象和活动对象构成,对象链具体构成过程见下面说明。
4、标识的查找机制:当javascript查询变量x的值时,就会检查此作用域链中第一个对象,可能是function的call object或全局对象(比如window),如果对象中有定义此x属性,则返回值,不然检查作用域链中的下一个对象是否定义x属性,在作用域链中没有找到,最后返回undefined。
5、当javascript执行一个function时,它会先将此function定义时的作用域作为其作用域链,然后创建一个活动对象(call object),置于作用域链的顶部,function的参数及内部var声明的所有局部变量都会成为此调用对象的属性。
6、this关键词指向方法的调用者,而不是以调用对象的属性存在,同一个方法中的this在不同的function调用中,可能指向不同的对象。
7、The Call Object as a Namespace。将活动对象当作命名空间使用,避免命名污染。
(function() {
// 在方法体内用var声明的所有局部变量,都是以方法调用时创建的活对象的属性形式 存在。
// 这样就避免与全局变量发生命名冲突。
})();
8、javascript中所有的function都是一个闭包,但只有当一个嵌套函数被导出到它所定义的作用域外时,这种闭包才强大。如果理解了闭包,就会理解function执行时的作用域链和活动对象,才能真正掌握javascript。
9、嵌套闭包的微观世界:在嵌套闭包时,当内部函数的引用被保存到嵌套闭包之外一个全局变量或者一个对象的属性时,在这种情况下,此内部函数有一个外部引用,并且在其外围调用函数的活动对象中有一个属性指向此内部函数。因为有其他对象引用此内部函数,所以在外围函数被调用一次后,其创建的活动对象会继续存在,并不会被垃圾回收器回收(因为引用计数不为0),内部函数的参数和局部变量都会在这个活动对象中得以维持,javascript代码任何形式都不能直接访问此活动对象,但是此活动对象是内部函数被调用时创建的作用域链的一部分,可以被内部函数访问并修改。
<html>
<head>
<title>循环内的闭包 应该谨慎</title>
</head>
<body>
<ul id="list">
<li>第1条记录</li>
<li>第2条记录</li>
<li>第3条记录</li>
<li>第4条记录</li>
<li>第5条记录</li>
<li>第6条记录</li>
</ul>
<script type="text/javascript">
var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组
for (var i = 0; i <= list_obj.length; i++) {
list_obj[i].onmousemove = function() {
this.style.backgroundColor = "#eee";
document.title=i
};
list_obj[i].onmouseout = function() {
this.style.backgroundColor = "#fff";
}
}
</script>
</body>
</html> 为什么上面的代码改成下面的就好了呢?
<html>
<head>
<title>循环内的闭包 应该谨慎</title>
</head>
<body>
<ul id="list">
<li>第1条记录</li>
<li>第2条记录</li>
<li>第3条记录</li>
<li>第4条记录</li>
<li>第5条记录</li>
<li>第6条记录</li>
</ul>
<script type="text/javascript">
var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组
for (var i = 0; i <= list_obj.length; i++) {
(function(i){
list_obj[i].onmousemove = function() {
this.style.backgroundColor = "#eee";
document.title=i
};
list_obj[i].onmouseout = function() {
this.style.backgroundColor = "#fff";
}
})(i);
}
</script>
</body>
</html>
分享到:
相关推荐
JavaScript中的闭包、匿名函数和作用域链是编程中至关重要的概念,它们是理解JavaScript运行机制的关键。在本文中,我们将深入探讨这三个概念,并通过实际示例来展示它们的运用。 首先,我们来讨论“闭包”。闭包是...
当函数执行时,会创建一个运行期上下文,其中的作用域链初始化为当前函数的[[Scope]]。运行期上下文的作用域链用于标识符解析,确保函数可以访问到在其定义时存在的变量和函数。 每次函数调用时,都会创建一个新的...
`)仅在该函数作用域内可见,而外部变量(如`out_var`)则可以通过作用域链在内部访问。闭包是理解作用域链的关键概念,它允许内部函数记住其定义时的作用域,即使外部函数已经完成执行。闭包常常用于封装变量和实现...
在JavaScript编程中,作用域链和闭包是两个至关重要的概念,它们对于理解代码执行机制以及函数内部如何访问和管理变量至关重要。让我们深入探讨这两个概念。 首先,**作用域链**是JavaScript中的一种机制,它定义了...
本文将深入探讨JavaScript中的函数、递归和闭包,以及执行环境、变量对象与作用域链的概念。 首先,我们来看JavaScript中定义函数的两种方式:函数声明和函数表达式。函数声明是一种明确的、独立的代码结构,例如`...
闭包的形成基于两个关键概念:作用域链(Scope Chain)和执行上下文(Execution Context)。 1. **作用域链**: - 在每个函数创建时,都会构建一个作用域链,用于存储函数可以访问的所有变量和函数。 - 作用域链...
执行上下文有一个自己的作用域链,这个链是在函数作用域链的基础上初始化的。 **活动对象(Active Object)**是执行上下文的一部分,它包含了函数的所有局部变量、参数和`this`。当函数执行时,活动对象被创建并推...
前端面试题,包含JavaScript的闭包,作用域,原型,原型链,上下文环境以及DOM,BOM封装函数深度克隆,以及一些常见的·JS问题,试题简单但是容易混淆,作为前端工程师必考题
- **函数作用域**:JavaScript的变量作用域主要分为函数作用域和全局作用域。函数作用域意味着变量在其定义的函数内部有效。在函数内部定义的变量不能在函数外部访问,而函数外部定义的变量可以在函数内部访问。 -...
全局作用域的变量在整个脚本中都可访问,而函数作用域的变量只在其定义的函数内可见。ES6引入了块级作用域,使得在`{}`中的`let`和`const`声明的变量只在其所在的代码块内有效。闭包是一种特殊的作用域现象,它允许...
"作用域链和闭包:代码中出现相同的变量,JavaScript引擎是如何选择的?" 标题“作用域链和闭包:代码中出现相同的变量,JavaScript引擎是如何选择的?”中,我们可以看到JavaScript引擎是如何选择相同的变量的。...
### JS的作用域与闭包 #### 一、作用域的基础概念 作用域是JavaScript中一个非常核心的概念,它定义了变量的可见性和生命周期。在学习作用域之前,我们需要先了解几个基本概念: - **变量**: 在JavaScript中,...
接着讨论了 JavaScript 中的全局作用域、局部作用域、块级作用域和函数作用域,特别是闭包的概念。随后,文章探讨了函数的高级用法,如递归函数、高阶函数和立即执行函数表达式(IIFE)。最后,通过实际应用示例,如...
作用域链主要涉及到函数执行上下文和全局执行上下文中的作用域。以下是对这个主题的详细解释: 首先,每个函数在创建时,都会有一个内部属性[[scope]],它保存了函数的作用域链。作用域链是由一系列对象构成的列表...
例如,全局环境中的变量`fruit`和函数`fn1`存储在`window`对象中,而在函数`fn1`内部定义的变量`my_favorite`则存储在函数作用域的变量对象中。 作用域链的建立是为了在不同作用域间共享和查找变量。每当代码在某个...
在JavaScript中,作用域分为全局作用域和局部作用域(函数作用域)。作用域链则是一系列嵌套的作用域。在函数执行时,当前作用域内部找不到某个变量时,会沿着作用域链向上查找,直到找到该变量的定义或者达到全局...
理解闭包的关键在于,当内部函数引用外部函数的变量时,它会捕获这些变量的当前值,形成一个“作用域快照”。这意味着即使外部函数执行完毕,闭包仍然可以访问并操作这些变量。 举个例子,下面的代码展示了闭包的...
每个JavaScript代码块(全局或函数)都有一个与之关联的作用域链。这个链是由多个环境记录组成的,它们定义了变量所在的范围。当我们查找一个变量时,JavaScript会从当前作用域开始,沿着作用域链向上搜索,直到找到...
- **作用域链**:当一个函数被创建时,它会捕获一个**作用域链**,这个链包含了函数内部的作用域、包含该函数的作用域以及全局作用域。 - **内存保留**:如果一个函数返回了一个闭包,那么该函数的作用域(包括所有...