【JavaScript】关于闭包

1、闭包是函数的代码在运行过程中的一个动态环境,是一个运行期的、动态的概念。
       闭包(又称“词法闭包”或“函数闭包”)是一个包含了非本地变量引用环境的函数。
2、变量在语法分析阶段被初始化为undefined。
//   标识符   ( 变量   ) 在定义后值为 undefined
function myFunc() {
      alert(i);
      var i = 100;
}
// 输出值总是undefined
myFunc();
myFunc();
//name在函数闭包内被声明, 不会访问到全局变量  name
var name = 'test';
function myFunc() {
      // 输出undefined
      alert(name);
      var name = 100;
      // 输出100 
      alert(name);
}
3、以下函数返回( return 子句)并不导致引用:
function myFunc() {
      function foo() {
      //...
      }
      return foo;
}
// 函数  foo() 在返回后立即被执行了,然后就会释放
foo()();
4、引用:
对象属性的引用:
      1)对象在构造时,使用   this   引用进入构造器函数
      2)对象在调用方法时,使用   this   引用进入函数
      3)某个函数使用   call/apply   方法调用,并传入某个对象作为   this   引用
      4)调用一个函数时,对象从参数入口传入
被变量引用:
     var  func = myFunc(); // <-- 在这里产生一个引用
5、函数闭包间的关联性:
var checker;
function myFunc() 
{
     if (checker) {
            checker();
      }
      alert('do myFunc: ' + str);
      var str = 'test.';
      if (!checker) {
           checker = function() {
           alert('do Check:' + str);
           }
      }
      return arguments.callee;
}
  myFunc()();
// do myFunc:  undefined  第一次调用
//do Check:test.  第二次调用
// do myFunc:  undefined 第二次调用
6、
范例1:
var obj = new Object();
var events = { m1: "clicked", m2: "changed" };
for (e in events) {
      obj[e] = function(){
      alert(events[e]);
      };
}
// 显示false, 表明是不同的函数实例
alert( obj.m1 === obj.m2 );
// 方法m1()与m2()都输出相同值
// 其原因,在于两个方法都访问全局闭包中的同一个upvalue 值e
obj.m1();
obj.m2();
范例2:
// 范例 2.1  在函数内保存数据
var obj = new Object();
var events = { m1: "clicked", m2: "changed" };
for (e in events) {
      obj[e] = function( aValue) { // 闭包 lv1
           return function() { // 闭包lv2
                alert(events[ aValue]);
           }
      }(e);
}
// 下面将输出不同的值
obj.m1();

obj.m2();

// 范例 2.2  在闭包内通过局部变量保存数据
for (e in events) {
      function() { // 闭包lv1
           var aValue = e;
           obj[e] = function() { // 闭包lv2
                alert(events[ aValue]);
           }
      }();

}

// 范例 2.3  将值 e   交给函数实例保存
for (e in events) {
      (obj[e] = function() {
           // arguments.callee 指向匿名函数自身
           alert(events[arguments.callee .aValue]);
      }
      ) .aValue = e;

}

// 范例 2.4  Function构造器
var obj = new Object();
var events = {m1: "clicked", m2: "changed"};
for (e in events) {
           obj[e] = new Function('alert( events["' + e + '"])');// 变量e被转换为字符串值来使
}

7、优先级:argsName(形式参数名) > arguments > funcName(函数名),其中arguments 是语言内定的标识符,无需声明即可使用。  
// 示例1:输出值'hi', 而非函数foo.toString()
function foo(foo) {
      alert(foo);
}
foo('hi');
// 示例2:输出数值100 的类型'number', 而非参数对象arguments 的类型'object'
function foo2(arguments) {
      alert(typeof arguments);
}
foo2(100);
// 示例3:输出参数对象arguments 的类型'object'
// (注:在JScript 中, arguments 作为函数名可以被声明, 但调用该函数导致脚本引擎崩溃)
function arguments () {
      alert(typeof arguments);
}
arguments ();
8、局部变量 (varDecls)与函数形式参数:
     A. 当形式参数名与未赋值的局部变量名重复时   ,   取形式参数值;
     B. 当形式参数与有值的局部变量名重复时,取局部变量值。
第一种情况:
function myFunc(str){
     var str;
     alert(str);
}
myFunc("not undefined");   //not undefined
第二种情况:
function myFun(str){
     var str = "hello world";
     alert(str);
}
myFun("not undefined");  //hello world
9、使用Function()构造器创建的函数与函数直接量声明、匿名函数不同,它在任意位置创建的实例,都处于全局闭包中。亦即是说, Function()的实例的upvalue 总是指向全局闭包。
var value = "hello world";
function myFunc(arg){
     var value = "welcome to here";
     var foo = new Function('alert(value)');
     foo();
}
myFunc();  //   "hello world"
 10、对象闭包:
var aObj = { value: 'hello' };
function foo() {
     with (aObj) {  // < --对象闭包
           var value = 1000;
            alert(aObj.value); // 显示值: 1000
       }
       alert(value);
}
foo();    // 显示'undefined'
11、函数闭包与对象闭包既有相关性,也有各自的独立性。对象闭包总是动态地添加在闭包链的顶端,而函数闭包则依赖于函数声明时的、静态的语法作用域限制。 
/**
* 两种闭包的交叉作用  
*/
var obj = { value: 200 };
var value = 1000;
with (obj) { // <-- 对象闭包
      function foo() { // <-- 具名函数foo()的闭包
      value *= 2; // <-- 依赖于函数静态位置所决定的闭包链
      }
      foo();     // with  的限定只对这一行有效
}
alert(obj.value);// 显示 200
alert(value);   // 显示 2000
12、匿名函数的闭包如同对象闭包一样,动态地添加到当前闭包链的顶端。
var obj = { value: 200 };
var value = 1000;
with (obj) { // <-- 对象闭包
    obj. foo =   function ()  {   // <-- 匿名函数的闭包
      value *= 2;   //   <-- 依赖于函数闭包所在的当前闭包链:with所打开的obj对象闭包
      }
    obj. foo();  
}
/**
* 即使该匿名函数没 有添加为对象  obj  的方法
*而仅是即用即声明,那么它所操作的仍然是对象 闭包中的  value 
*/
with (obj) { // <-- 对象闭包
      void  function ()  {   // <-- 匿名函数的闭包
      value *= 2;   //  <-- 依赖于函数闭包所在的当前闭包链:with所打开的obj对象闭包
      }();
}
// 显示 400
alert(obj.value);
// 显示 1000
alert(value);
13、eval:
     解决eval作用域的方法:with ( objContext )eval (strScript) 。
     如:with ( window )eval (strScript) ; //eval在 全局作用域中执行

转载于:https://my.oschina.net/aram/blog/114285

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript中的闭包是指一个函数能够访问并使用其外部作用域中的变量,即使在该函数被调用之后,该外部作用域的上下文已经销毁。简单来说,闭包是指一个函数保留了对其词法作用域的引用,使得函数可以访问和操作外部作用域的变量。 在JavaScript中,闭包可以通过函数嵌套来创建。当一个函数在内部定义了另一个函数,并且内部函数引用了外部函数的变量,那么内部函数就形成了闭包闭包函数可以访问和修改外部函数的变量,即使在外部函数执行完毕后,这些变量依然存在于闭包函数的作用域中。 以下是一个闭包函数的例子: ```javascript function outerFunction() { var outerVariable = 'Hello'; function innerFunction() { console.log(outerVariable); } return innerFunction; } var closure = outerFunction(); closure(); // 输出 'Hello' ``` 在这个例子中,内部函数`innerFunction`形成了闭包,它可以访问和使用外部函数`outerFunction`中的变量`outerVariable`,即使`outerFunction`执行完毕后,闭包仍然可以访问和操作`outerVariable`的值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaScript中的闭包](https://blog.csdn.net/qq_44482048/article/details/128714553)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [轻松学习Javascript闭包函数](https://download.csdn.net/download/weixin_38628429/13018893)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [JavaScript闭包](https://blog.csdn.net/qq_57586976/article/details/127678306)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值