本文共 6869 字,大约阅读时间需要 22 分钟。
javascript 闭包
Learning a new language involves a series of steps, whereas its mastery is a product of patience, practice, mistakes, and experience.
学习一门新语言涉及一系列步骤,而掌握它则是耐心,实践,错误和经验的产物。
Some developers will have enough knowledge to deliver on features as per a client's demand, but it takes more than just that to be a good developer.
有些开发人员将具有足够的知识来根据客户的需求提供功能,但是要成为一名优秀的开发人员,不仅需要付出更多的努力。
A good developer is one who takes time to go back and get a good grasp of a language's underlying/core concepts.
优秀的开发人员是需要花费时间回头并很好地掌握该语言的基础/核心概念的开发人员。
Today we take a deeper look at JavaScript closures and hope that the knowledge you learn will be beneficial in your projects.
今天,我们对JavaScript闭包进行了更深入的研究,希望您所学的知识对您的项目有所帮助。
A JavaScript Closure is when an inner function has access to members of the outer function () even when executing outside the scope of the outer function.
JavaScript闭包是指内部函数即使在外部函数之外执行时也可以访问外部函数的成员( )。
Therefore, we cannot afford to talk about closure while leaving out functions and scope.
因此,我们不能在不考虑功能和范围的情况下谈论闭包。
Scope refers to the extent of visibility of a variable defined in a program. Ways to create scope in JavaScript are through: try-catch blocks
, functions
, the let keyword
with curly braces among others. We mainly have two variations of scope: the global scope and local scope.
范围是指程序中定义的变量的可见性范围 。 在JavaScript中创建作用域的方法是通过: try-catch blocks
, functions
,带有花括号的let keyword
等。 我们主要有两个范围的变体: 全局范围和局部范围 。
var initialBalance = 0 // Global Scopefunction deposit (amount) { /** * Local Scope * Code here has access to anything declared in the global scope */ var newBalance = parseInt(initialBalance) + parseInt(amount) return newBalance}
Each function in JavaScript creates its own local scope when declared.
JavaScript中的每个函数在声明时都会创建自己的本地范围。
This means that whatever is declared inside the function's local scope is not accessible from the outside. Consider the illustration below:
这意味着从外部无法访问在函数的本地范围内声明的任何内容。 考虑下图:
var initialBalance = 300 // Variable declared in the Global Scopefunction withdraw (amount) { var balance // Variable declared in function scope balance = parseInt(initialBalance) - parseInt(amount) return balance}console.log(initialBalance) // Will output initialBalance value as it is declared in the global scopeconsole.log(balance) // ReferenceError: Can't find variable: balance
JavaScript's is determined during the . It sets the scope of a variable so that it may only be called/referenced from within the block of code in which it is defined.
JavaScript的是在确定的。 它设置变量的范围,以便仅可以在定义该变量的代码块内调用/引用该变量。
A function declared inside a surrounding function block has access to variables in the surrounding function's lexical scope.
在周围功能块内部声明的功能可以访问周围功能的词法范围内的变量。
var initialBalance = 300 // Global Scopefunction withdraw (amount) { /** * Local Scope * Code here has access to anything declared in the global scope */ var balance = parseInt(initialBalance) - parseInt(amount) const actualBalance = (function () { const TRANSACTIONCOST = 35 return balance - TRANSACTIONCOST /** * Accesses balance variable from the lexical scope */ })() // Immediately Invoked Function expression. IIFE // console.log(TRANSACTIONCOST) // ReferenceError: Can't find variable: TRANSACTIONCOST return actualBalance}
Invoking an inner function outside of its enclosing function and yet maintain access to variables in its enclosing function (lexical scope) creates a JavaScript Closure.
在其封闭函数之外调用内部函数,但仍保持对其封闭函数(词法范围)中变量的访问会创建一个JavaScript闭包。
function person () { var name = 'Paul' // Local variable var actions = { speak: function () { // new function scope console.log('My name is ', name) /** * Accessing the name variable from the outer function scope (lexical scope) */ } } // actions object with a function return actions /** * We return the actions object * We then can invoke the speak function outside this scope */}person().speak() // Inner function invoked outside its lexical Scope
A Closure allows us to expose a public interface while at the same time hiding and preserving execution context from the outside scope.
闭包允许我们公开一个公共接口,同时从外部范围隐藏和保留执行上下文。
Some JavaScript design patterns make use of closures.
一些JavaScript设计模式使用了闭包。
One of these well-implemented patterns is the module pattern, this pattern allows you to emulate: private, public and privileged members.
模块模式是这些实现良好的模式之一,该模式可让您效仿:私有,公共和特权成员。
var Module = (function () { var foo = 'foo' // Private Property function addToFoo (bam) { // Private Method foo = bam return foo } var publicInterface = { bar: function () { // Public Method return 'bar' }, bam: function () { // Public Method return addToFoo('bam') // Invoking the private method } } return publicInterface // Object will contain public methods})()Module.bar() // barModule.bam() // bam
From our module pattern illustration above, only public methods and properties in the return object will be available outside the closure's execution context.
从上面的模块模式插图中,只有闭包的执行上下文之外,返回对象中的公共方法和属性才可用。
All private members will still exist as their execution context is preserved but hidden from the outside scope.
所有私有成员将仍然存在,因为它们的执行上下文得以保留,但对外部作用域是隐藏的。
When we pass a function into a setTimeout
or any kind of callback. The function still remembers the lexical scope because of the closure.
当我们将函数传递给setTimeout
或任何类型的回调时。 由于关闭,该函数仍记住词法范围。
function foo () { var bar = 'bar' setTimeout(function () { console.log(bar) }, 1000)}foo() // bar
Closure and loops
闭合和循环
for (var i = 1; i <= 5; i++) { (function (i) { setTimeout(function () { console.log(i) }, i * 1000) })(i)}/*** Prints 1 thorugh 5 after each second* Closure enables us to remember the variable i* An IIFE to pass in a new value of the variable i for each iteration* IIFE (Immediately Invoked Function expression)*/
for (let i = 1; i <= 5; i++) { (function (i) { setTimeout(function () { console.log(i) }, i * 1000) })(i)}/*** Prints 1 through 5 after each second* Closure enabling us to remember the variable i* The let keyword rebinds the value of i for each iteration*/
I bet we now have an understanding of closures and can do the following:
我敢打赌,我们现在对闭包有所了解,可以执行以下操作:
Until next time, happy coding.
直到下一次,快乐编码。
Credits
学分
翻译自:
javascript 闭包
转载地址:http://deuwd.baihongyu.com/