New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[js] 第14天 什么是闭包?优缺点分别是什么? #44
Comments
上面就是闭包,有独立的作用域,且作用域的变量不会在程序中释放 |
closure:关闭 |
|
闭包:在局部作用域引用上层作用域(非全局)的变量 |
闭包是可以访问另一个函数作用域的函数。由于 function a(){
var b = 1;
var c = 2;
// 这个函数就是个闭包,可以访问外层 a 函数的变量
return function(){
var d = 3;
return b + c + d;
}
}
var e = a();
console.log(e()); 因此,使用闭包可以隐藏变量以及防止变量被篡改和作用域的污染,从而实现封装。 |
感谢大佬的分享,讲的十分透彻。 |
闭包的定义:从外部访问或者操作函数内部变量的的方式,缓存数据,延长作用域链(JS是函数作用域) 例子:定义了一个内部变量,但是不想使这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作来访问,闭包的作用常常用来「间接访问一个变量」。换句话说,「隐藏一个变量」 缺点:函数中的变量不能及时的释放 function Foo(){
var name = "fooname"; //需要从外部访问这些变量
var age = 12;
this.getFoo = function(){ //设置访问方法
return name;
}
this.setFoo = function(){
return age;
}
this.xgFoo = function(new){
name = new;
}
}
var foo = new Foo();
foo.getFoo(); //访问name变量。
foo.xgFoo("liz") //从外部修改nage变量 |
当函数能够记住并访问所在的词法作用域,即使函数是在当时词法作用域之外执行,这是就产生了闭包。 词法作用域是变量或函数声明时,在词法解析阶段所在的作用域。 function foo() {
var a = 2;
function bar() {
console.log(a)
}
return bar
}
var baz = foo()
bar() // 2
这个 bar 函数在定义的词法作用域以外的地方被调用。闭包使得函数能够继续访问定义时的词法作用域。 无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论何时执行这个函数都会使用闭包。 |
定义看黑体字: 用法函数返回函数,形成局部作用域 优点局部作用域,防止变量污染 缺点内存泄露 面试官会问的在那里使用:命名空间/for循环取第i个处理为什么返回同一个i值(可以搜一下,老面试题了) |
闭包是一个函数,这个函数可以访问另一个函数的变量。(当你创建一个函数时你就创建了一个闭包) |
闭包就是声明在函数内部的函数(或者是可以访问外部函数变量的函数) |
函数中裹着函数就产生闭包,父函数访问子函数就是借用闭包的作用 |
函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。 |
闭包:在局部作用域引用上层作用域(非全局)的变量 |
从函数外部访问到函数内部的变量,函数内部的变量的作用域不会被释放,通常从函数内部返回一个函数。 |
简单说就是函数套函数,函数外部可以访问到内部的变量, |
概念当一个函数能够访问和操作另一个函数作用域中的变量时,就构成了一个闭包(closure) function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
//函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的 上面代码中的f2函数,就是闭包 由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数。 所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 优点:防止变量污染作用域缺点:不释放则会导致内存泄漏用途
注意
|
要理解闭包,首先要理解JS的变量作用域。变量的作用域有两种:全局变量和局部变量。JS语言的特别之处在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。那么如何从外部读取函数内部的局部变量?可以在函数内部再定义一个函数,如下所示: |
要理解闭包,首先要理解javascript的特殊的变量作用域。 |
作用域链:只能访问自身或外层作用域的变量。 function a(){
let n = 1;
return () => n;
}
a()() // 可以获取到a函数中声明的变量n 作用:
|
闭包: 当一个函数能访问和操作另一个函数作用域的变量时,此时就形成了闭包 |
一个函数可以访问另一个函数内的变量,当这个函数被运行时,就形成了一个闭包,因为这个变量因为被引用着,所以即使执行完毕了也不会被回收掉。 |
来自mdn的解析:闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。就是每一个函数都是一个闭包。 闭包是一个函数和它周围环境(词法环境)的引用的组合。 所以每一个函数可以形成一个闭包。 函数局部作用域,可以含有一些私有变量、私有函数(外部不能直接访问),结合函数的闭包,使得函数以外也可以通过函数内部的抛出的函数访问函数的私有变量和私有函数。function outerFn(){
// 私有变量,outerFn函数外不能直接访问
var _name = 'private name';
// 私有函数,outerFn函数外不能直接访问
function _fn(){
console.log("trigger private function")
}
// 返回一个方法,以供外部可以访问到outerFn的私有变量、函数
return function(){ // 返回的这个函数,可以访问_name、_fn()
console.log(_name)
_fn();
}
}
let fn = outerFn();
fn(); for循环问题html文件 <ul>
<li>xxxxxxxxxxx</li>
<li>xxxxxxxxxxx</li>
<li>xxxxxxxxxxx</li>
<li>xxxxxxxxxxx</li>
</ul> var liElements = document.getElementsByTagName('li');
for(var i=0; i< liElements.length; i++){
liElements[i].onclick = function(){
console.log(i); // 因为 变量i 是公用一个词法环境,所以最终输出的都一样,都输出 4
}
} 可以用新的函数来隔开不同的i,使得获取的i在不同的词法环境 var liElements = document.getElementsByTagName('li');
for(var i=0; i< liElements.length; i++){
liElements[i].onclick = (function(i){ // 利用自执行匿名函数,给每一个元素的onclick事件分隔开了不同值的i
return function(){
console.log(i); // 分别输出 0、1、2、3
}
})(i)
} var liElements = document.getElementsByTagName('li');
Array.prototype.forEach.call(liElements, function(item, i){ // 利用匿名函数,给每一个元素的onclick事件分隔开了不同值的i
liElements[i].onclick = function () {
console.log(i)
}
}) 或者使用ES2015 引入的 let 关键词 var liElements = document.getElementsByTagName('li');
for (let i = 0; i < liElements.length; i++) {
liElements[i].onclick = function () {
console.log(i); // 分别输出 0、1、2、3
}
} |
|
闭包就可以在全局函数里面操作另一个作用域的局部变量! |
第14天 什么是闭包?优缺点分别是什么?
The text was updated successfully, but these errors were encountered: