Title: 作用域闭包 · Issue #30 · paddingme/Learning-JavaScript · GitHub
Open Graph Title: 作用域闭包 · Issue #30 · paddingme/Learning-JavaScript
X Title: 作用域闭包 · Issue #30 · paddingme/Learning-JavaScript
Description: 看起来像闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } bar(); } foo(); 这才是闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz(); 把内部函数 baz 传递给 bar, 当调用这个内部函数时(现在叫做 fn),它涵盖的 fo...
Open Graph Description: 看起来像闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } bar(); } foo(); 这才是闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz(); 把内部函数 ...
X Description: 看起来像闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } bar(); } foo(); 这才是闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz(); 把内部函数 ...
Opengraph URL: https://github.com/paddingme/Learning-JavaScript/issues/30
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"作用域闭包","articleBody":"1. 看起来像闭包。\n \n ``` js\n function foo(){\n var a = 2;\n function bar(){\n console.log(a);\n }\n bar();\n }\n foo();\n ```\n2. 这才是闭包。\n \n ``` js\n function foo(){\n var a = 2;\n function bar(){\n console.log(a);\n }\n return bar;\n }\n var baz = foo();\n baz();\n ```\n3. 把内部函数 baz 传递给 bar, 当调用这个内部函数时(现在叫做 fn),它涵盖的 foo()\n 内部作用域的闭包就可以观察到了。因此它能够访问 a。\n \n ``` js\n function foo() {\n var a = 2;\n function baz(){\n console.log(a);\n }\n bar(baz);\n }\n function bar(fn) {\n fn();\n }\n ```\n4. 把 baz 分配给全局变量\n \n ``` js\n var fn;\n function foo(){\n var a = 2;\n function baz(){\n console.log(a);\n }\n fn = baz;\n }\n function bar(){\n fn();\n }\n foo();\n bar();\n ```\n5. 无论通过何种手段将内部函数传递到所在的词法作用域以外, \n 它都会持有对原始定义作用有的引用, \n 无论在何处执行这个函数都会使用闭包。\n \n ``` js\n function wait(message) {\n setTimeout(function timer(){\n console.log(message);\n },1000)\n }\n wait(\"Hello,Closure!\")\n ```\n \n /*\n jquery\n */\n \n ``` js\n function setupBot(name,selector){\n $(selector).click(function activator(){\n console.log(\"Activating: \" + name);\n });\n }\n setupBot(\"console BOT1\",\"#bot_1\");\n setupBot(\"console BOT2\",\"#bot_2\");\n ```\n6. IIFE\n \n ``` js\n var a = 2;\n (function IIFE(){\n console.log(a);\n })();\n ```\n7. 循环和闭包\n \n ``` js\n for(var i = 1; i \u003c= 5; i++) {\n setTimeout(function timer(){\n console.log(i)\n },i*1000)\n }\n \n \n for(var i = 0; i\u003c=5; i++) {\n (function(j){\n setInterval(function(){\n console.log(j);\n },1000);\n })(i);\n }\n ```\n \n ``` js\n // 每隔一秒钟打印1,2,3,4,5\n function foo(arr){\n var i = 0;\n return function(){\n setInterval(function(){\n console.log(arr[i++]);\n },1000);\n }()\n }\n ```\n \n ``` js\n (function(arr){\n var i=0,length=arr.length;\n (function a(){\n setTimeout(function(){\n console.log(arr[i++]);\n i\u003clength\u0026\u0026a();\n },1000)\n }())\n }([1,2,3,4]))\n ```\n8. 模块\n \n ``` js\n function coolModule() {\n var sth = \"cool\";\n var another = [1,2,3];\n function doSth() {\n console.log(sth);\n }\n function doAnother() {\n console.log(another.join(\"!\"));\n }\n return {\n doSth: doSth,\n doAnother : doAnother\n }\n }\n var foo = new coolModule();\n foo.doSth();\n foo.doAnother();\n ```\n9. 模块模式需要两个必要条件:\n 1. 必须有外部的封闭函数,该函数必须至少\n 被调用一次(每次调用都会创建一个新的模块实例)\n 2. 封闭函数必须至少返回至少一个内部函数,\n 这样内部函数才能在私有作用域中形成闭包,\n 并且可以访问或者修改私有的状态。\n10. 模块模式另一个简单强大的变化用法是,命名将要作为公共API 返回的对象。\n \n ``` js\n var foo = (function coolModule(id){\n function change(){\n publicAPI.identify = identify2;\n }\n function identify1(){\n console.log(id);\n }\n function identify2(){\n console.log(id.toUpperCase());\n }\n var publicAPI = {\n change:change,\n identify: identify1\n };\n return publicAPI;\n })(\"foo module\");\n foo.identify();\n foo.change();\n foo.identify();\n ```\n11. 现代的模块管理\n \n ``` js\n var MyModules = (function Manger() {\n var modules = {};\n function define(name, deps, impl) {\n for (var i = 0; i \u003c deps.length; i++) {\n deps[i] = modules[deps[i]];\n }\n modules[name] = impl.apply(impl, deps);\n }\n function get(name) {\n return modules[name];\n }\n return {\n define: define,\n get: get\n }\n })();\n \n MyModules.define(\"bar\", [], function() {\n function hello(who) {\n return \"Let me introduce: \" + who;\n }\n return {\n hello: hello\n };\n });\n MyModules.define(\"foo\", [\"bar\"], function(bar) {\n var hungry = \"hippo\";\n function awesome() {\n console.log(bar.hello(hungry).toUpperCase());\n }\n return {\n awesome: awesome\n };\n });\n var bar = MyModules.get(\"bar\");\n var foo = MyModules.get(\"foo\");\n console.log(bar.hello(\"hippo\"));\n foo.awesome();\n ```\n\n当函数可以记住并访问所在的词法作用域,即使函数时在当前词法作用域之外执行,这时就产生了闭包。\n\n模块有两个主要特征: \n1. 为创建内部作用域而调用了一个包装函数;\n2. 包装函数的返回值必须至少包含一个队内部函数的引用,这样就会创建涵盖整个包装函数内部作用域的闭包。\n","author":{"url":"https://github.com/paddingme","@type":"Person","name":"paddingme"},"datePublished":"2015-08-22T13:50:56.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/30/Learning-JavaScript/issues/30"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:9db64c1f-b9bb-447b-761f-08a19a0d5d04 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 9A46:225DC1:A207613:DA5242D:6A5EA957 |
| html-safe-nonce | 668348fe75e9051f1da3d77973643182162aa7b3d51b71831e391adf964c2609 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5QTQ2OjIyNURDMTpBMjA3NjEzOkRBNTI0MkQ6NkE1RUE5NTciLCJ2aXNpdG9yX2lkIjoiODA0NDc2NTEzOTI0ODc4NTc1MSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 6bce0053b0d42169ad9cf9d615d9f84933040529cc317ba377353671ed6b8270 |
| hovercard-subject-tag | issue:102538266 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/paddingme/Learning-JavaScript/30/issue_layout |
| twitter:image | https://opengraph.githubassets.com/7b706d980df36e9277e21e8a9da7820808d8c83aa7b2f144b1f0791ce5e690eb/paddingme/Learning-JavaScript/issues/30 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/7b706d980df36e9277e21e8a9da7820808d8c83aa7b2f144b1f0791ce5e690eb/paddingme/Learning-JavaScript/issues/30 |
| og:image:alt | 看起来像闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } bar(); } foo(); 这才是闭包。 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz(); 把内部函数 ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | paddingme |
| hostname | github.com |
| expected-hostname | github.com |
| None | 7c7e31acb6a895494e518b880f5ccf39604f7fa9a8f2f3c64145efc3b776256d |
| turbo-cache-control | no-preview |
| go-import | github.com/paddingme/Learning-JavaScript git https://github.com/paddingme/Learning-JavaScript.git |
| octolytics-dimension-user_id | 5771087 |
| octolytics-dimension-user_login | paddingme |
| octolytics-dimension-repository_id | 25473884 |
| octolytics-dimension-repository_nwo | paddingme/Learning-JavaScript |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 25473884 |
| octolytics-dimension-repository_network_root_nwo | paddingme/Learning-JavaScript |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 2d2ac9bdd71d5f53f2b731c9330677e38624e301 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width