从C++/Java转过来学JS有点不习惯,JS闭包这个表达式()()连续两个括号?为什么把还可以把function括起来然后又加一个()啊。
比如这个,把这个迭代器function括起来,加参数(i),外面的括号(0)就表示调用0了,把0传进去i。
还有这个,
var a = 6;
(function() {
var a = 5;
})();
a = 6//true。
这个闭包创造新的作用域,闭包一定是()()这种表达式吗?为什么是这个规范。
抱歉,初学JS,很不习惯。
从C++/Java转过来学JS有点不习惯,JS闭包这个表达式()()连续两个括号?为什么把还可以把function括起来然后又加一个()啊。
比如这个,把这个迭代器function括起来,加参数(i),外面的括号(0)就表示调用0了,把0传进去i。
还有这个,
var a = 6;
(function() {
var a = 5;
})();
a = 6//true。
这个闭包创造新的作用域,闭包一定是()()这种表达式吗?为什么是这个规范。
抱歉,初学JS,很不习惯。
闭包是实现函数式编程过程中的一部分。在函数式编程里,函数的返回值可以是函数。
函数调用可以是fn()
, 那么如果,如果函数可以返回函数那么就可以otherFn = fn(); otherFn();
写到一起就可以是fn()();
不像其他语言,函数式编程的所有函数都被认为是只接收一个参数,函数只接受一个参数。多个参数的函数,比如两个参数的函数,其实也是接受一个参数的函数,只是它的返回值是另外一个函数! 比如加法add(2)(5)
,其实 add
只接收一个参数,然后返回了一个函数2+
,再以参数 5
调用这个2+
函数,那个这个2+
函数就返回一个7
。
var a = 6;
// (function() {
// var a = 5;
// })();
// 可以写成这样
function f() { var a = 5; }
f();
// 这段代码可以说是不涉及闭包
// 这个跟C JAVA里的局部变量没有区别,只是他们不支持前一种的调用而已
a = 6//true。
因为在函数式编程里函数和基本类型没有区别,(function() {var a = 5;})
的返回值就是一个函数,var fn = function() {var a = 5;}
也没有问题,然后后面在加一个()
表示函数调用(这样使用的时候前面加括号的原因就是改变优先级,函数调用()
的优先级比定义一个函数高,所以不加会出现错误)。
可能对初学者有点儿难的闭包教程:http://zonxin.github.io/post/...
()
块在 JS 就是对象的意思,把 function 包起来,就是取定义的函数对象。这个括号你不能理解为函数定义和调用中包裹参数用的,而可以理解为 a * (b + c)
或 ("abc" + xyz).length
这里的括号。
哎,想想还是不扯“闭包”了,我也说不清,多余的删了。关于闭包的偏官方文档链接(中文),希望对您有帮助。
闭包不是指两个括号的作用问题,而是指把你想使用的函数和变量用一个大的函数来包起来,变量是在你需要调用函数的外面,你每次调用你需要的那个函数时,那个函数里面调用那个变量是会常驻在你的内存里面的,类似于使用了memcache来存储数据一样,但是闭包会有些性能问题,使用不当会导致你所在的环境出问题。
10 回答11.7k 阅读
2 回答3.2k 阅读✓ 已解决
3 回答2.7k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
3 回答805 阅读✓ 已解决
首先要明确的是js中的基本概念
js主要的作用域形式就是
全局作用域
与函数作用域
(局部作用域),没有块级作用域,不过在ES6中用let
声明的变量具有块级作用域的效果。执行环境分为全局执行环境和函数执行环境,就是当前代码的执行上下文,简单说就是定义了变量或函数访问其他数据的权限,控制着变量和函数的可见性与生命周期,每个执行环境都有一个与之关联的对象即变量对象,环境中定义的所有变量和函数都保存在这个对象中。全局环境是最外围的,而每个函数有自己的执行环境。
代码在一个环境中执行时就会创建变量对象的一个作用域链,作用域链前端始终是当前执行环境的变量对象,下一个变量对象来自包含(外部的)环境,全局执行环境的变量对象始终是作用域链的最后一个对象,就像洋葱一样,如果你愿意一层一层剥开它的心,就很好理解了。
立即执行函数表达式
()
这括号有两种意义,一是指代一个表达式,二是表示函数执行。上面的效果就是很好的创建了一个作用域,可以做到外部作用域中不能够访问内部,就好像被屏蔽了一样。所以上面你在全局环境声明变量a又在函数环境声明a两个就没什么联系了,两个处于不同的变量对象内部,虽然名字相同。但是如果你在函数内部不声明a,而是直接
a = 5
赋值,则外部的a会改变,这是因为内部通过作用域链访问到外部的变量并赋值。理解了作用域链就很好理解这些问题了。最后,什么是闭包?,答:就是能访问局部变量的函数!!方式是如下(实质还是通过作用域链)