谈论javascript闭包
闭包看似很简单,其实牵扯了很多东西,例如:上下文作用域(事件处理程序)、内存占用、局部以及全局变量、回调函数以及编程模式等
首先我们谈论一个问题,为什么需要闭包?
1.var全局定义(全局污染)- 指的是同一变量名会影响到所有的同名变量。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="Test.js"></script> <!-- <script src="Tests.js"></script> --> <script> console.log(ok); </script> </head> <body> </body> </html>
运行好像真的没问题,没关系,我们试一试下面
//Test.js
var ok = "666";
//Tests.js
var ok = "999";
搞什么嘛,明明是不同JavaScript文件 - 牵扯到JavaScript引擎对JavaScript的处理机制。
2.ES6相对于ES5,增加了const 、let声明变量的方式(你该知道它们为什么出世的)。
//Test.js let ok = "666";
//Tests.js var ok = "999";
当我们其中一个js文件使用了Let同名变量声明后,浏览器报错了
说该变量已经被使用了! 当我们更改了Tests.js同名变量以后,浏览器会作何反应呢?
//Tests.js var oks = "999";
它显示了let定义的变量值
Let只能被变量同名定义一次,记住了! 下面这个示例会告诉你
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 <script src="Test.js"></script> 10 <script src="Tests.js"></script> 11 <script> 12 let ok = "000"; 13 console.log(ok); 14 </script> 15 </head> 16 17 <body> 18 19 </body> 20 21 </html>
const 又是怎么回事呢?(const只能被赋值一次,且不可修改,以后可修改的只能是它的对象元素)
//Test.js // var ok ="666"; let ok = "666"; const ju = "888";
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 <script src="Test.js"></script> 10 <script src="Tests.js"></script> 11 <script> 12 const ju = "111"; 13 console.log(ju); 14 </script> 15 </head> 16 17 <body> 18 19 </body> 20 21 </html>
什么是闭包
闭包允许你从内部函数访问外部函数的作用域。
在JavaScript中,每次创建函数时都会在函数创建时创建闭包。
要使用闭包,只需在另一个函数内定义一个函数并将其暴露。要公开一个函数,将其返回或传递给另一个函数。
即使在外部函数返回后,内部函数也可以访问外部函数作用域中的变量。
在JavaScript中,闭包是用于启用数据隐私的主要机制。当您使用闭包实现数据隐私时,封闭变量只在包含(外部)函数的范围内。
除了通过对象的特权方法外,您无法从外部范围获取数据。在JavaScript中,在闭包范围内定义的任何公开方法都是有特权的。
data-private.js
1 const getSecret = (secret) => { 2 return { 3 get: () => secret 4 }; 5 }; 6 7 test('Closure for object privacy.', assert => { 8 const msg = '.get() should have access to the closure.'; 9 const expected = 1; 10 const obj = getSecret(1); 11 12 const actual = obj.get(); 13 14 try { 15 assert.ok(secret, 'This throws an error.'); 16 } catch (e) { 17 assert.ok(true, `The secret var is only available 18 to privileged methods.`); 19 } 20 21 assert.equal(actual, expected, msg); 22 assert.end(); 23 });