资讯专栏INFORMATION COLUMN

js 闭包理解笔记

liuyix / 385人阅读

摘要:发现指向的是,也就是说,在函数内部实现的闭包函数已经被转变成了全局函数,存储到了内存中。闭包同样可以模拟面向对象的私有变量的方法和变量的使用和获取。

https://developer.mozilla.org...
首先引用来自官网文档的定义:
closure is the combination of a function and the lexical environment within which that function was declared.
闭包是一个函数和其内部公开变量的环境的集合.

简单而言, 闭包 = 函数 + 环境

第一个闭包的例子
function init() {
  var name = "Mozilla"; // name is a local variable created by init
  function displayName() { // displayName() is the inner function, a closure
    alert(name); // use variable declared in the parent function    
  }
  displayName();    
}
init();

because inner functions have access to the variables of outer functions, displayName() can access the variable name declared in the parent function, init().

其实这个栗子很简单,displayName()就是init()内部的闭包函数,而为啥在displayName内部可以调用到外部定义的变量 name 呢,因为js内部函数有获取外部函数中变量的权限

第二个栗子
var data = [
    {"key":0},
    {"key":1},
    {"key":2}
];
function showKey() {
    for(var i=0;i

上面这个例子可以正确输出 10 11 12 吗?
答案是:并不能,并且还会报语法错误....

console.log(i); 发现i输出了3次3,也就是说,在setTimeout 1000毫秒之后,执行闭包函数的时候,for循环已经执行结束了,i是固定值,并没有实现我们期望的效果。

console.log(this); 发现 this 指向的是 Window,也就是说,在函数内部实现的闭包函数已经被转变成了全局函数,存储到了内存中。

所以需要再定义一个执行函数

var data = [
    {"key":0},
    {"key":1},
    {"key":2}
];
function showKey() {
    var f1 = function(n){
        data[i].key = data[i].key + 10;
        console.log(data[i].key)
    }
    for(var i=0;i
第三个闭包的例子-柯里化(currying)
function makeAdder(x) {
  return function(y) {
    return function(z) {
        return x + y + z;
    }
  };
}

console.log(makeAdder(1)(2)(3)); // 6

// function factory it creates functions which can add a specific value to their argument
var add5 = makeAdder(5);
console.log(add5(1)(2));  // 8
console.log(add5(4)(5));  // 14

这种返回function的形式就是柯里化,作用是 makeAdder 可以作为一个 function factory来使用。

第四个闭包的例子 - practicle closure

闭包的适用场景:当你想要通过一个function来操作它关联的数据时,闭包是很有用的,这种使用方法是类似面向对象的。

闭包同样可以模拟面向对象的私有变量的方法和变量的使用和获取。

var counter = (function() {
  // private variable
  var privateCounter = 0; 

  // private function
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    changeValue: function(val) {
      changeBy(val);
    },
    value: function() {
      return privateCounter;
    }
  };   
})();

console.log(counter.value()); // logs 0 // 实现了内部属性的获取
counter.changeValue(2);// 实现了内部的changeBy()方法
counter.changeValue(10); 
console.log(counter.value()); // logs 12
counter.changeValue(-5);
console.log(counter.value()); // logs 7

counter对外暴露的方法就是 counter.changeValue, counter.value,而内部属性 privateCounter 和 内部方法 changeBy 被隔离开了,只能通过外部方法来调用。

同时我们也可以定义多个 counter,其内部属性也是相互隔离的。

var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var counter1 = makeCounter();
var counter2 = makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94312.html

相关文章

  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0
  • 《你不知道的JS》读书笔记---作用域及闭包

    摘要:注此读书笔记只记录本人原先不太理解的内容经过阅读你不知道的后的理解。作用域及闭包基础,代码运行的幕后工作者引擎及编译器。 注:此读书笔记只记录本人原先不太理解的内容经过阅读《你不知道的JS》后的理解。 作用域及闭包基础,JS代码运行的幕后工作者:引擎及编译器。引擎负责JS程序的编译及执行,编译器负责词法分析和代码生成。那么作用域就像一个容器,引擎及编译器都从这里提取东西。 ...

    denson 评论0 收藏0
  • [学习笔记] JavaScript 闭包

    摘要:但是,必须强调,闭包是一个运行期概念。通过原型链可以实现继承,而与闭包相关的就是作用域链。常理来说,一个函数执行完毕,其执行环境的作用域链会被销毁。所以此时,的作用域链虽然销毁了,但是其活动对象仍在内存中。 学习Javascript闭包(Closure)javascript的闭包JavaScript 闭包深入理解(closure)理解 Javascript 的闭包JavaScript ...

    sunsmell 评论0 收藏0
  • JS学习笔记——闭包

    摘要:什么是闭包定义我所理解的闭包就是,即使外部函数已经运行完毕,内部函数仍能访问外部函数的作用域中的变量。闭包的应用场景私有变量模块需求只能通过函数提供的方法访问函数内部的变量隐藏。为什么闭包很重要参考资料征服面试什么是闭包 1. 什么是闭包 MDN定义:Closures are functions that refer to independent (free) variables (v...

    Karuru 评论0 收藏0
  • 前端学习笔记闭包——看了一张图终于明白啥是闭包

    摘要:在一个闭包环境内修改变量值,不会影响另一个闭包中的变量。直到看到函数闭包闭包这篇文章的代码一部分,终于明白其中的逻辑了。 闭包 闭包定义:指拥有多个变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。函数内部可以直接读取全局变量。函数内部变量无法在函数外部访问。函数内部声明要用var或者let声明,不然会变成全局变量链式作用域:子对象会一级级向上寻找...

    andycall 评论0 收藏0

发表评论

0条评论

liuyix

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<