From ccb6e120689b7375d8f693108a12e945a9842504 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:22:20 +0900 Subject: [PATCH 01/16] Added basic translation system --- exercises/closures/{ => en}/fail.md | 0 exercises/closures/{ => en}/pass.md | 0 exercises/closures/{ => en}/problem.md | 0 exercises/closures/{ => en}/solution.md | 0 exercises/garbage-collection/{ => en}/fail.md | 0 exercises/garbage-collection/{ => en}/pass.md | 0 .../garbage-collection/{ => en}/problem.md | 0 .../garbage-collection/{ => en}/solution.md | 0 .../{ => en}/fail.md | 0 .../{ => en}/pass.md | 0 .../{ => en}/problem.md | 0 .../{ => en}/solution.md | 0 exercises/scope-chains/{ => en}/fail.md | 0 exercises/scope-chains/{ => en}/pass.md | 0 exercises/scope-chains/{ => en}/problem.md | 0 exercises/scope-chains/{ => en}/solution.md | 0 exercises/scopes/{ => en}/fail.md | 0 exercises/scopes/{ => en}/pass.md | 0 exercises/scopes/{ => en}/problem.md | 0 exercises/scopes/{ => en}/solution.md | 0 i18n/ja.json | 9 ++++++ problem.js | 28 +++++++++++-------- runner.js | 12 +++++--- 23 files changed, 33 insertions(+), 16 deletions(-) rename exercises/closures/{ => en}/fail.md (100%) rename exercises/closures/{ => en}/pass.md (100%) rename exercises/closures/{ => en}/problem.md (100%) rename exercises/closures/{ => en}/solution.md (100%) rename exercises/garbage-collection/{ => en}/fail.md (100%) rename exercises/garbage-collection/{ => en}/pass.md (100%) rename exercises/garbage-collection/{ => en}/problem.md (100%) rename exercises/garbage-collection/{ => en}/solution.md (100%) rename exercises/global-scope-and-shadowing/{ => en}/fail.md (100%) rename exercises/global-scope-and-shadowing/{ => en}/pass.md (100%) rename exercises/global-scope-and-shadowing/{ => en}/problem.md (100%) rename exercises/global-scope-and-shadowing/{ => en}/solution.md (100%) rename exercises/scope-chains/{ => en}/fail.md (100%) rename exercises/scope-chains/{ => en}/pass.md (100%) rename exercises/scope-chains/{ => en}/problem.md (100%) rename exercises/scope-chains/{ => en}/solution.md (100%) rename exercises/scopes/{ => en}/fail.md (100%) rename exercises/scopes/{ => en}/pass.md (100%) rename exercises/scopes/{ => en}/problem.md (100%) rename exercises/scopes/{ => en}/solution.md (100%) create mode 100644 i18n/ja.json diff --git a/exercises/closures/fail.md b/exercises/closures/en/fail.md similarity index 100% rename from exercises/closures/fail.md rename to exercises/closures/en/fail.md diff --git a/exercises/closures/pass.md b/exercises/closures/en/pass.md similarity index 100% rename from exercises/closures/pass.md rename to exercises/closures/en/pass.md diff --git a/exercises/closures/problem.md b/exercises/closures/en/problem.md similarity index 100% rename from exercises/closures/problem.md rename to exercises/closures/en/problem.md diff --git a/exercises/closures/solution.md b/exercises/closures/en/solution.md similarity index 100% rename from exercises/closures/solution.md rename to exercises/closures/en/solution.md diff --git a/exercises/garbage-collection/fail.md b/exercises/garbage-collection/en/fail.md similarity index 100% rename from exercises/garbage-collection/fail.md rename to exercises/garbage-collection/en/fail.md diff --git a/exercises/garbage-collection/pass.md b/exercises/garbage-collection/en/pass.md similarity index 100% rename from exercises/garbage-collection/pass.md rename to exercises/garbage-collection/en/pass.md diff --git a/exercises/garbage-collection/problem.md b/exercises/garbage-collection/en/problem.md similarity index 100% rename from exercises/garbage-collection/problem.md rename to exercises/garbage-collection/en/problem.md diff --git a/exercises/garbage-collection/solution.md b/exercises/garbage-collection/en/solution.md similarity index 100% rename from exercises/garbage-collection/solution.md rename to exercises/garbage-collection/en/solution.md diff --git a/exercises/global-scope-and-shadowing/fail.md b/exercises/global-scope-and-shadowing/en/fail.md similarity index 100% rename from exercises/global-scope-and-shadowing/fail.md rename to exercises/global-scope-and-shadowing/en/fail.md diff --git a/exercises/global-scope-and-shadowing/pass.md b/exercises/global-scope-and-shadowing/en/pass.md similarity index 100% rename from exercises/global-scope-and-shadowing/pass.md rename to exercises/global-scope-and-shadowing/en/pass.md diff --git a/exercises/global-scope-and-shadowing/problem.md b/exercises/global-scope-and-shadowing/en/problem.md similarity index 100% rename from exercises/global-scope-and-shadowing/problem.md rename to exercises/global-scope-and-shadowing/en/problem.md diff --git a/exercises/global-scope-and-shadowing/solution.md b/exercises/global-scope-and-shadowing/en/solution.md similarity index 100% rename from exercises/global-scope-and-shadowing/solution.md rename to exercises/global-scope-and-shadowing/en/solution.md diff --git a/exercises/scope-chains/fail.md b/exercises/scope-chains/en/fail.md similarity index 100% rename from exercises/scope-chains/fail.md rename to exercises/scope-chains/en/fail.md diff --git a/exercises/scope-chains/pass.md b/exercises/scope-chains/en/pass.md similarity index 100% rename from exercises/scope-chains/pass.md rename to exercises/scope-chains/en/pass.md diff --git a/exercises/scope-chains/problem.md b/exercises/scope-chains/en/problem.md similarity index 100% rename from exercises/scope-chains/problem.md rename to exercises/scope-chains/en/problem.md diff --git a/exercises/scope-chains/solution.md b/exercises/scope-chains/en/solution.md similarity index 100% rename from exercises/scope-chains/solution.md rename to exercises/scope-chains/en/solution.md diff --git a/exercises/scopes/fail.md b/exercises/scopes/en/fail.md similarity index 100% rename from exercises/scopes/fail.md rename to exercises/scopes/en/fail.md diff --git a/exercises/scopes/pass.md b/exercises/scopes/en/pass.md similarity index 100% rename from exercises/scopes/pass.md rename to exercises/scopes/en/pass.md diff --git a/exercises/scopes/problem.md b/exercises/scopes/en/problem.md similarity index 100% rename from exercises/scopes/problem.md rename to exercises/scopes/en/problem.md diff --git a/exercises/scopes/solution.md b/exercises/scopes/en/solution.md similarity index 100% rename from exercises/scopes/solution.md rename to exercises/scopes/en/solution.md diff --git a/i18n/ja.json b/i18n/ja.json new file mode 100644 index 0000000..d692936 --- /dev/null +++ b/i18n/ja.json @@ -0,0 +1,9 @@ +{ + "exercise": { + "1. Scopes": "1. Scopes", + "2. Scope Chains": "2. Scope Chains", + "3. Global Scope & Shadowing": "3. Global Scope & Shadowing", + "4. Closures": "4. Closures", + "5. Garbage Collection": "5. Garbage Collection" + } +} \ No newline at end of file diff --git a/problem.js b/problem.js index d9d7788..866d632 100644 --- a/problem.js +++ b/problem.js @@ -2,18 +2,22 @@ var msee = require('msee'), path = require('path'), verify = require('adventure-verify'); -module.exports = function(dir, testCorrect) { - - var problem = { + module.exports = function(dir, testCorrect) { + + var problem = { + init: function (exercise) { + ['problem', 'solution', 'pass', 'fail'].forEach(function(type) { + problem[type] = function () { + return msee.parseFile( + dir + '/' + exercise.lang + '/' + type + '.md', + {paragraphEnd: '\n\n'} + ); + } + }); + }, verify: verify({ modeReset: true }, testCorrect) }; + + return problem; + }; - ['problem', 'solution', 'pass', 'fail'].forEach(function(type) { - problem[type] = msee.parseFile( - dir + '/' + type + '.md', - {paragraphEnd: '\n\n'} - ); - }); - - return problem; -}; diff --git a/runner.js b/runner.js index db1f51d..7f4a283 100755 --- a/runner.js +++ b/runner.js @@ -2,10 +2,14 @@ 'use strict'; -var packageJson = require('./package.json'), - adventure = require('adventure'); - -var shop = adventure(packageJson.name), + var packageJson = require('./package.json'), + adventure = require('workshopper-adventure/adventure'); + +var shop = adventure({ + name: packageJson.name, + appDir: __dirname, + languages: ['en', 'ja'] +}), lesson; [ From 169c4acd67235f6b840a4d153b87c3e48719be49 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 18 Jun 2015 21:22:02 +0900 Subject: [PATCH 02/16] Added japanese stubs --- closures/ja/fail.md | 12 ++ closures/ja/pass.md | 4 + closures/ja/problem.md | 58 ++++++++++ closures/ja/solution.md | 27 +++++ garbage-collection/ja/fail.md | 19 +++ garbage-collection/ja/pass.md | 1 + garbage-collection/ja/problem.md | 76 ++++++++++++ garbage-collection/ja/solution.md | 6 + global-scope-and-shadowing/ja/fail.md | 12 ++ global-scope-and-shadowing/ja/pass.md | 4 + global-scope-and-shadowing/ja/problem.md | 114 ++++++++++++++++++ global-scope-and-shadowing/ja/solution.md | 28 +++++ scope-chains/ja/fail.md | 12 ++ scope-chains/ja/pass.md | 3 + scope-chains/ja/problem.md | 135 ++++++++++++++++++++++ scope-chains/ja/solution.md | 26 +++++ scopes/ja/fail.md | 13 +++ scopes/ja/pass.md | 4 + scopes/ja/problem.md | 66 +++++++++++ scopes/ja/solution.md | 15 +++ 20 files changed, 635 insertions(+) create mode 100644 closures/ja/fail.md create mode 100644 closures/ja/pass.md create mode 100644 closures/ja/problem.md create mode 100644 closures/ja/solution.md create mode 100644 garbage-collection/ja/fail.md create mode 100644 garbage-collection/ja/pass.md create mode 100644 garbage-collection/ja/problem.md create mode 100644 garbage-collection/ja/solution.md create mode 100644 global-scope-and-shadowing/ja/fail.md create mode 100644 global-scope-and-shadowing/ja/pass.md create mode 100644 global-scope-and-shadowing/ja/problem.md create mode 100644 global-scope-and-shadowing/ja/solution.md create mode 100644 scope-chains/ja/fail.md create mode 100644 scope-chains/ja/pass.md create mode 100644 scope-chains/ja/problem.md create mode 100644 scope-chains/ja/solution.md create mode 100644 scopes/ja/fail.md create mode 100644 scopes/ja/pass.md create mode 100644 scopes/ja/problem.md create mode 100644 scopes/ja/solution.md diff --git a/closures/ja/fail.md b/closures/ja/fail.md new file mode 100644 index 0000000..5d6f9f4 --- /dev/null +++ b/closures/ja/fail.md @@ -0,0 +1,12 @@ +# Almost there! + +Check the errors above to see where you went wrong. + +# Hints + + * The task is to return the function `zip`, not the result of `zip()`. + * The value you set to `bar` isn't important. + +# More Help + + * If you're still having troubles, post a question in the nodeschool issues repository: http://bit.ly/scope-chains-question diff --git a/closures/ja/pass.md b/closures/ja/pass.md new file mode 100644 index 0000000..df938f3 --- /dev/null +++ b/closures/ja/pass.md @@ -0,0 +1,4 @@ +# Success! + +Awesome stuff - you closed over the variable `bar` inside `zip`, then returned +`zip`. diff --git a/closures/ja/problem.md b/closures/ja/problem.md new file mode 100644 index 0000000..2dff9c0 --- /dev/null +++ b/closures/ja/problem.md @@ -0,0 +1,58 @@ +# Closures + +Closures are an important part of the Javascript language. They are what enables +the callback-last programming most prominent in node, and provide an excellent +mechanism for handling the asynchronous nature of most Javascript tasks. + +To properly understand closures, let's start with an example scope chain: + +``` +someFunc() + ↑ + | + inner() + ↑ + | + foo() +``` + +Let's say `someFunc()` declares a variable `bar`: + +``` +someFunc() + var bar + ↑ + ⋮ +``` + +Given how nesting scope works, it's possible for an inner scope within +`someFunc()` to access `bar`. In this example, let's say `inner()` accesses +`bar`: + +``` +someFunc() + var bar + ↑ + | + inner() +alert(bar) + ↑ + ⋮ +``` + +Then `inner()` is said to _Close Over_ `bar`. Therefore `inner()` is a _Closure_. + +To power the callback style of programming, the closure will be maintained even +if `inner()` isn't executed immediately. It is perfectly legal in Javascript to +pass `inner` around / return it from `someFunc()` for later execution. All the +while, `bar` will continue to be available. + +---- + +# Your Mission + +Modify your solution from the previous lesson to set `bar = true` inside `zip()`, +then return the function `zip` as the result of `foo()` + +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your +solution. diff --git a/closures/ja/solution.md b/closures/ja/solution.md new file mode 100644 index 0000000..b3b8450 --- /dev/null +++ b/closures/ja/solution.md @@ -0,0 +1,27 @@ +---- + +# Solution + +Let's look at the scope chain for your solution: + +``` + foo() + var bar +return zip + ↑ + | + zip() +bar = true +``` + +By referencing `bar` within `zip`, we have created a _Closure_ where `zip()` _closes over_ the variable `bar` from its parent scope `foo()`. + +Since we are returning the function `zip`, the reference to `bar` is maintained (and hence the closure is maintained) until `zip` is no longer required. + +This has interesting implications for memory, which we will cover in the next lesson. + +---- + +# Next lesson + +Execute `$ADVENTURE_COMMAND` to move on to the next lesson: _Garbage Collection_. diff --git a/garbage-collection/ja/fail.md b/garbage-collection/ja/fail.md new file mode 100644 index 0000000..b30f303 --- /dev/null +++ b/garbage-collection/ja/fail.md @@ -0,0 +1,19 @@ +# Unknown error..? + +Congratulations! If you've made it to this screen, you deserve a nyan cat as a +reward :D + +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ +░░░░░░░░░░▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄░░░░░░░░░ +░░░░░░░░▄▀░░░░░░░░░░░░▄░░░░░░░▀▄░░░░░░░ +░░░░░░░░█░░▄░░░░▄░░░░░░░░░░░░░░█░░░░░░░ +░░░░░░░░█░░░░░░░░░░░░▄█▄▄░░▄░░░█░▄▄▄░░░ +░▄▄▄▄▄░░█░░░░░░▀░░░░▀█░░▀▄░░░░░█▀▀░██░░ +░██▄▀██▄█░░░▄░░░░░░░██░░░░▀▀▀▀▀░░░░██░░ +░░▀██▄▀██░░░░░░░░▀░██▀░░░░░░░░░░░░░▀██░ +░░░░▀████░▀░░░░▄░░░██░░░▄█░░░░▄░▄█░░██░ +░░░░░░░▀█░░░░▄░░░░░██░░░░▄░░░▄░░▄░░░██░ +░░░░░░░▄█▄░░░░░░░░░░░▀▄░░▀▀▀▀▀▀▀▀░░▄▀░░ +░░░░░░█▀▀█████████▀▀▀▀████████████▀░░░░ +░░░░░░████▀░░███▀░░░░░░▀███░░▀██▀░░░░░░ +░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ diff --git a/garbage-collection/ja/pass.md b/garbage-collection/ja/pass.md new file mode 100644 index 0000000..e05d4fc --- /dev/null +++ b/garbage-collection/ja/pass.md @@ -0,0 +1 @@ +# Everything Looks Good Here... diff --git a/garbage-collection/ja/problem.md b/garbage-collection/ja/problem.md new file mode 100644 index 0000000..b9e6193 --- /dev/null +++ b/garbage-collection/ja/problem.md @@ -0,0 +1,76 @@ +# Garbage Collection + +Memory in Javascript is managed automatically by the runtime. The runtime +decides when/if to release any allocated memory. This decision process is called +_Garbage Collection_. + +Every javascript runtime has their own algorithm for garbage collection, but +most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by +marking references to memory (variables, functions, etc) which are still +reachable from active code. Any reference which is not marked, is swept into +the garbage (i.e. the memory is freed). + +This concept of marking reachable memory is particulary relevant to closures: + +``` + someFunc() + var bar +return inner + ↑ + | + inner() + alert(bar) + ↑ + ⋮ +``` + +When the closure `inner()` is returned from `someFunc()`, it maintains its +reference to `bar`. The Mark & Sweep algorithm will mark `bar` as reachable, and +hence will _not_ garbage collect it. + +For `inner()` to correctly resolve its reference to `bar`, not only does the +memory for `bar` need to be kept, but the scope chain which describes how to +reach `bar` must also be kept. + +Once the reference to `inner()` is no longer required, it can be marked for +garbage collection, which in turn means `bar` can also be marked, and finally +the entire scope chain can be marked, resulting in the freeing of all the +memory. + +In this way, Scope, Scope Chains, Closures, and Garbage Collection are all +closely related. + +---- + +# Your Mission + +In this challenge, you will be required to use Chrome DevTools for detecting +Garbage Collection events. Follow these steps to get a feel for what happens +when Chrome performs its Mark & Sweep algorithm: + +1) Fire up a new tab in Chrome +2) Open the DevTools > Timeline tab +3) Ensure the settings are like so: `http://i.imgur.com/RMovIw4.png` + a) Frames View is unselected (allows seeing memory graphs) + b) Flame Chart View is selected (allows seeing where execution time is spent) + c) Only "Memory" is selected from the options +4) Click the solid gray record button to begin capturing data +5) Visit `http://www.stackoverflow.com` (or your favourite website) +6) Click the now-red record button to stop capturing data +7) You should now see something similar to: `http://i.imgur.com/ZCNMrI1.png` +8) The part we're interested in is when memory suddenly drops: + `http://i.imgur.com/FyMyRVI.png` +9) Click this drop in memory to select it +10) Now look for the yellow event called "GC Event": `http://i.imgur.com/3ieSxIZ.png` +11) Clicking this event will reveal information about total memory garbage + collected, and how long it took. + +One particularly interesting thing of note here is the length of time Garbage +Collection can take: Often well beyond the 16ms maximum required to keep it +within a single frame (at 60fps). While garbage collection occurs, it blocks the +main thread, which means other Javascript cannot be executed until the event +completes. Be conscious of how janky your application may become due to +extensive Garbage Collection events! + +**Note**: If you'd like to get that lovely `[COMPLETED]` label for this lesson, +Run `$ADVENTURE_COMMAND verify` diff --git a/garbage-collection/ja/solution.md b/garbage-collection/ja/solution.md new file mode 100644 index 0000000..19aeb35 --- /dev/null +++ b/garbage-collection/ja/solution.md @@ -0,0 +1,6 @@ +---- + +# Congratulations! + +Now that you know all about Scope Chains, Closures, & Garbage Collection, why +not tweet about it: `http://bit.ly/sccjs-twitter-share` diff --git a/global-scope-and-shadowing/ja/fail.md b/global-scope-and-shadowing/ja/fail.md new file mode 100644 index 0000000..635acb4 --- /dev/null +++ b/global-scope-and-shadowing/ja/fail.md @@ -0,0 +1,12 @@ +# Almost there! + +Check the errors above to see where you went wrong. + +# Hints + + * Modifying your solution to lesson 2, _Scope Chains_, is a good start. + * Don't use `var` or `let` when assigning the value to `quux` inside `foo()` + +# More Help + + * If you're still having troubles, post a question in the nodeschool issues repository: http://bit.ly/scope-chains-question diff --git a/global-scope-and-shadowing/ja/pass.md b/global-scope-and-shadowing/ja/pass.md new file mode 100644 index 0000000..6706d0d --- /dev/null +++ b/global-scope-and-shadowing/ja/pass.md @@ -0,0 +1,4 @@ +# Success! + +You assigned a value to `quux`, even though `foo()` doesn't have access to the +`quux` inside `zip()`. diff --git a/global-scope-and-shadowing/ja/problem.md b/global-scope-and-shadowing/ja/problem.md new file mode 100644 index 0000000..9614d09 --- /dev/null +++ b/global-scope-and-shadowing/ja/problem.md @@ -0,0 +1,114 @@ +# Global Scope & Shadowing + +## Global Scope + +Understanding where Scope Chains end is an important part of scoping. All +Javascript runtimes must implicitly create a _Global Scope_ object (`window` in +the browser, `global` in node), which sits at the top of every scope chain: + +``` + (global) + ↑ + | + someFunc() + ↑ + / \ + / \ + / \ +inner() inner2() + ↑ + | + foo() +``` + +In _Scopes_ we covered how usage of `var` or `let` dictates the scope of the +variable being defined. When assigning a variable without using either of `var`, +`let`, etc, the variable is assumed to exist in an outer scope. + +The javascript runtime follows these steps to assign a variable: + + 1) Search within the current scope. + 2) If not found, search in the immediately outer scope. + 3) If found, go to 6. + 4) If not found, repeat 2. Until the Global Scope is reached. + 5) If not found in Global Scope, create it (on `window` / `global` objects). + 6) Assign the value. + +In this way, it is possible to accidentally define a global variable (step 5). + +### Example Global Scope + +Consider the following example: + +```js +function someFunc() { + var scopedVar = 1; + function inner() { + foo = 2; + } +} +``` + +Note the lack of `var` or `let`, etc for `foo = 2`. The Javascript runtime will +follow the above algorithm, first checking the scope of `inner()`, then of +`someFunc()`, then finally the Global Scope. Step 5 is then executed, so `foo` +becomes a variable in the Global Scope (`window.foo` / `global.foo`). + +Phrased another way: By accidentally forgetting to use `var`, the variable `foo` +which otherwise would have been only within the lexical scope of `inner()` is +now available to be modified by _any_ scope. So, `someFunc()` now has access +where the developer may have meant for it not to. + +_Remember: Only inner scopes can access variables of outer scopes. In this case +the `someFunc()` scope is an inner scope of the Global Scope, allowing access of +`foo` to `someFunc()`._ + +## Shadowing + +A variable is created in a 'Step 0)' of the above algorithm: When `var` or `let` +is used. The variable is assigned to the correct scope, then execution moves on, +and any assignments to that variable follow the above algorithm. + +It is perfectly valid to define two different variables, in different scopes, +with the same name: + +```js +function someFunc() { + var foo = 1; +} +function anotherFunc() { + var foo = 2; +} +``` + +It is also valid to do this in nested scopes: + +```js +function someFunc() { + var foo = 1; + function inner() { + var foo = 2; + } +} +``` + +This is called _Shadowing_. The `foo` inside `inner()` is said to _Shadow_ the `foo` +inside `someFunc`. + +Shadowing means that the `inner()` scope only has access to its own `foo`. There +is no way for it to access the `foo` defined in `someFunc()`. + +This can also be an accidental source of bugs, especially when there is deep +nesting, or long functions. + +---- + +# Your Mission + +Starting with your solution from the previous lesson, assign a value to `quux` +inside `foo()` (don't use `var` or `let`). The value should be different to the +value assigned when defining `quux` inside `zip()`. + +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your +solution. + diff --git a/global-scope-and-shadowing/ja/solution.md b/global-scope-and-shadowing/ja/solution.md new file mode 100644 index 0000000..ada00b6 --- /dev/null +++ b/global-scope-and-shadowing/ja/solution.md @@ -0,0 +1,28 @@ +---- + +# Solution + +The scope chain of the solution looks like this: + +``` +(global) + quux + ↑ + | + foo() + var bar + ↑ + | + zip() + var quux +``` + +Following the arrows, we can see that the `quux` assigned inside `foo()` has +become globally scoped. This is a different `quux` from the one inside `zip()`, +which now shadows the globally scoped `quux`. + +---- + +# Next lesson + +Execute `$ADVENTURE_COMMAND` to move on to the next lesson: _Closures_. diff --git a/scope-chains/ja/fail.md b/scope-chains/ja/fail.md new file mode 100644 index 0000000..5563801 --- /dev/null +++ b/scope-chains/ja/fail.md @@ -0,0 +1,12 @@ +# Almost there! + +Check the errors above to see where you went wrong. + +# Hints + + * Modifying your solution to lesson 1, _Scopes_, is a good start. + * Ensure you've named your variables correctly (`foo`, `bar`, `zip`, & `quux`). + +# More Help + + * If you're still having troubles, post a question in the nodeschool issues repository: http://bit.ly/scope-chains-question diff --git a/scope-chains/ja/pass.md b/scope-chains/ja/pass.md new file mode 100644 index 0000000..7cad8d2 --- /dev/null +++ b/scope-chains/ja/pass.md @@ -0,0 +1,3 @@ +# Success! + +You created a scope chain using lexical scoping and `var` statements! diff --git a/scope-chains/ja/problem.md b/scope-chains/ja/problem.md new file mode 100644 index 0000000..f5cf54d --- /dev/null +++ b/scope-chains/ja/problem.md @@ -0,0 +1,135 @@ +# Scope Chains + +## Nesting + +Scopes can be nested. Both Lexical and Block scopes can contain other scopes: + +```js +function someFunc() { + function inner() { + } +} +``` +*`inner` is a nested lexical scope inside the lexical scope of `someFunc`* + +---- + +```js +if (true) { + while (false) { + } +} +``` +*The `while` is a nested block scope inside the block scope of `if`* + +---- + +```js +function someFunc() { + if (true) { + } +} +``` +*The `if` is a nested block scope inside the lexical scope of `someFunc`* + +---- + +## Scoped Variable Access + +All nested scopes follow the same rule: Each nested inner scope has access to +outer scope variables, but *NOT* vice-versa. + +For example: + +```js +function someFunc() { + var outerVar = 1; + function inner() { + var innerVar = 2; + } +} +``` +*`inner` has access to both `innerVar` & `outerVar`, but `someFunc`* only *has +access to `outerVar`* + +## Multiple Nested Scopes + +Nesting isn't limited to a single inner scope, there can be multiple nested +scopes, each of which adhere to the *Scoped Variable Access* rule above. With +one addition: sibling scopes are also restricted from accessing each other's +variables. + +For example: +```js +function someFunc() { + function inner() { + } + function inner2() { + } +} +``` +*`inner` & `inner2` are both inner scopes of `someFunc`. Just as `someFunc` +cannot access `inner`'s variables, `inner` cannot access `inner2`'s variables +(and vice versa)* + +## Scope Tree + +Looking at the nesting from top-down, a tree of scopes is formed. + +This code + +```js +function someFunc() { + function inner() { + } + function inner2() { + function foo() { + } + } +} +``` +Produces this tree +``` + someFunc() + | + / \ + / \ + / \ + ↓ ↓ +inner() inner2() + | + ↓ + foo() +``` + +Remembering that inner scopes can access outer scope's variables, but *not* +vice-versa (`foo()` can access `inner2()`'s variables, and `inner2()` can access +`someFunc()`'s variables), then it makes more sense to look at the tree from +bottom-up, which forms a chain, also known as... + +## Scope Chains + +Looking from most inner to most outer scope forms a *Scope Chain*. + +``` + someFunc() + ↑ + \ + \ + \ + inner2() + ↑ + | + foo() +``` + + +---- + +# Your Mission + +Modify your solution from lesson 1 so `foo` contains a function `zip` +which itself contains one variable lexically scoped called `quux` + +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your +solution. diff --git a/scope-chains/ja/solution.md b/scope-chains/ja/solution.md new file mode 100644 index 0000000..caa1d0f --- /dev/null +++ b/scope-chains/ja/solution.md @@ -0,0 +1,26 @@ +---- + +# Solution + +The scope chain you created now looks like this: + +``` +(global) + ↑ + | + foo() + var bar + ↑ + | + zip() + var quux +``` + +By following the arrows, we can see `zip()` has access to `var bar`, but not the +other way around. + +---- + +# Next lesson + +Execute `$ADVENTURE_COMMAND` to move on to the next lesson: _Global Scope & Shadowing_. diff --git a/scopes/ja/fail.md b/scopes/ja/fail.md new file mode 100644 index 0000000..cca0677 --- /dev/null +++ b/scopes/ja/fail.md @@ -0,0 +1,13 @@ +# Almost there! + +Check the errors above to see where you went wrong. + +# Hints + + * Ensure you've created the variable using `var` to give it correct scope + * Don't over think this problem - we're only getting warmed up. + * Ensure you've named your variables correctly (`foo` & `bar`). + +# More Help + + * If you're still having troubles, post a question in the nodeschool issues repository: http://bit.ly/scope-chains-question diff --git a/scopes/ja/pass.md b/scopes/ja/pass.md new file mode 100644 index 0000000..6ebdc3a --- /dev/null +++ b/scopes/ja/pass.md @@ -0,0 +1,4 @@ +# Success! + +You correctly created the variable `bar`, lexically scoped inside the function +`foo()`, great work. diff --git a/scopes/ja/problem.md b/scopes/ja/problem.md new file mode 100644 index 0000000..c4f4d46 --- /dev/null +++ b/scopes/ja/problem.md @@ -0,0 +1,66 @@ +# Scope Chains And Closures Workshop + +Scope, Scope Chains, Closures, and Garbage Collection all have one thing in +common: They're often hand-waved away. How do closures actually work? When does +Garbage Collection occur? What really IS a Scope Chain? + +In this workshop, we will discover it's not black magic after all; No hand +waving is required to explain these language features, in fact you've been using +them all along without realising. + +---- + +# Scopes + +The main type of scope in Javascript is Lexical Scoping. Present in the language +from the very beginning, this is the scope created within a function, and the +one most developers are familiar with.[1] + +ES6 recently defined Block Scoping. This scope is created within curly braced +blocks.[2] + +## Initializing Variables + +The way a variable is initialized determines which scope type it is: + +### Lexical Scope + +`var` is used to denote a variable which is Lexically Scoped to the current +function: + +```js +function someFunc() { + var aVariable; +} +``` + +*`aVariable` is lexically scoped within `someFunc`* + +### Block Scope + +`let` & `const` are used to denote variables which are Block Scoped to the +current curly braced block: + +```js +if (true) { + let aVariable; +} +``` + +*`aVariable` is block scoped within the `if`'s curly braces* + +---- + +# Your Mission + +In an empty file, create a function `foo` which contains one variable lexically +scoped named `bar`. + +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your +solution. + +## Notes + + * [1]: There are also 4 other scopes in the language: Global, `with`, `catch`, + and `eval`. These tend not to be used much, so we will ignore them. + * [2]: This workshop will concentrate only on Lexical Scoping. diff --git a/scopes/ja/solution.md b/scopes/ja/solution.md new file mode 100644 index 0000000..2a2b490 --- /dev/null +++ b/scopes/ja/solution.md @@ -0,0 +1,15 @@ +---- + +# Solution + +For comparison, here is a possible solution, so you can compare notes: + +```js +function foo() { + var bar; +} +``` + +# Next lesson + +Execute `$ADVENTURE_COMMAND` to move on to the next lesson: _Scope Chains_. From 17772ff9ec41e1cd7345e63900d5b7f9b5106365 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:23:13 +0900 Subject: [PATCH 03/16] skipping bug --- problem.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/problem.js b/problem.js index 866d632..b89d41c 100644 --- a/problem.js +++ b/problem.js @@ -2,22 +2,21 @@ var msee = require('msee'), path = require('path'), verify = require('adventure-verify'); - module.exports = function(dir, testCorrect) { - - var problem = { +module.exports = function(dir, testCorrect) { + + var problem = { init: function (exercise) { - ['problem', 'solution', 'pass', 'fail'].forEach(function(type) { + ['problem', 'solution', 'pass', 'fail'].forEach(function(type) { problem[type] = function () { return msee.parseFile( dir + '/' + exercise.lang + '/' + type + '.md', - {paragraphEnd: '\n\n'} - ); + {paragraphEnd: '\n\n'} + ); } - }); + }); }, verify: verify({ modeReset: true }, testCorrect) }; - - return problem; - }; + return problem; +}; From f566268b5f3fbf6d328147de54572a17f22751fc Mon Sep 17 00:00:00 2001 From: goodseason Date: Tue, 7 Jul 2015 20:16:52 +0900 Subject: [PATCH 04/16] translate into Japanese (only Question 1) --- scopes/ja/fail.md | 16 ++++++------ scopes/ja/pass.md | 5 ++-- scopes/ja/problem.md | 59 +++++++++++++++++++------------------------ scopes/ja/solution.md | 8 +++--- 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/scopes/ja/fail.md b/scopes/ja/fail.md index cca0677..8f83c50 100644 --- a/scopes/ja/fail.md +++ b/scopes/ja/fail.md @@ -1,13 +1,13 @@ -# Almost there! +# おしい! -Check the errors above to see where you went wrong. +エラーメッセージを確認してどこが間違っているかチェックしましょう。 -# Hints +# ヒント - * Ensure you've created the variable using `var` to give it correct scope - * Don't over think this problem - we're only getting warmed up. - * Ensure you've named your variables correctly (`foo` & `bar`). + * 正しいスコープを持った変数とするために`var`を使っているか確認しましょう。 + * ウォーミングアップですので考えすぎないようにしましょう。 + * 変数名が正しいか確認しましょう(`foo` や `bar`)。 -# More Help +# ヘルプ - * If you're still having troubles, post a question in the nodeschool issues repository: http://bit.ly/scope-chains-question + * 問題が解決しない場合は、nodeschool issuesリポジトリに質問してみましょう。:http://bit.ly/scope-chains-question diff --git a/scopes/ja/pass.md b/scopes/ja/pass.md index 6ebdc3a..2b3817b 100644 --- a/scopes/ja/pass.md +++ b/scopes/ja/pass.md @@ -1,4 +1,3 @@ -# Success! +# 正解! -You correctly created the variable `bar`, lexically scoped inside the function -`foo()`, great work. +`foo()`関数をレキシカルスコープとする変数`bar`を作ることができました。いいね! diff --git a/scopes/ja/problem.md b/scopes/ja/problem.md index c4f4d46..a401a68 100644 --- a/scopes/ja/problem.md +++ b/scopes/ja/problem.md @@ -1,32 +1,29 @@ # Scope Chains And Closures Workshop -Scope, Scope Chains, Closures, and Garbage Collection all have one thing in -common: They're often hand-waved away. How do closures actually work? When does -Garbage Collection occur? What really IS a Scope Chain? - -In this workshop, we will discover it's not black magic after all; No hand -waving is required to explain these language features, in fact you've been using -them all along without realising. +スコープ、スコープチェーン、クロージャ、そしてガーベジコレクション。 +これらに共通するのは。。。「なんとなくわかるようで、よくわからない」という点。 +クロージャは実際どう動いているの? +ガーベジコレクションはいつ起動されるの? +スコープチェーンっていったい何者? +実際誰も気づかない間に使っているこのあやふやなモノを +ワークショップを通してクリアにしていきましょう。 ---- -# Scopes +# スコープ -The main type of scope in Javascript is Lexical Scoping. Present in the language -from the very beginning, this is the scope created within a function, and the -one most developers are familiar with.[1] +JavaScriptでスコープといえば基本的に「レキシカルスコープ」になります。 +「関数」というスコープは初歩的であり開発者にとってはイメージしやすいでしょう。[1] -ES6 recently defined Block Scoping. This scope is created within curly braced -blocks.[2] +最近、ES6では中括弧でスコープを定義する「ブロックスコープ」という概念も生まれました。[2] -## Initializing Variables +## 変数の初期化 -The way a variable is initialized determines which scope type it is: +スコープの種類によって変数の初期化のしかたが変わります。 -### Lexical Scope +### レキシカルスコープ -`var` is used to denote a variable which is Lexically Scoped to the current -function: +関数内をスコープとする変数は`var`を使って宣言します。 ```js function someFunc() { @@ -34,12 +31,11 @@ function someFunc() { } ``` -*`aVariable` is lexically scoped within `someFunc`* +*この例で`aVariable`は`someFunc`関数のレキシカルスコープとなります。* -### Block Scope +### ブロックスコープ -`let` & `const` are used to denote variables which are Block Scoped to the -current curly braced block: +中括弧でかこまれた範囲をスコープとする変数は`let` や `const`で宣言します。 ```js if (true) { @@ -47,20 +43,17 @@ if (true) { } ``` -*`aVariable` is block scoped within the `if`'s curly braces* +*この例で`aVariable` は`if`構文内のブロックスコープとなります* ---- -# Your Mission - -In an empty file, create a function `foo` which contains one variable lexically -scoped named `bar`. +# 課題 -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +空ファイルの中に「レキシカルスコープ変数`bar`を持つ`foo`関数」を作りましょう。 +作り終えたら `$ADVENTURE_COMMAND verify ` を実行し答え合わせしましょう。 -## Notes +## メモ - * [1]: There are also 4 other scopes in the language: Global, `with`, `catch`, - and `eval`. These tend not to be used much, so we will ignore them. - * [2]: This workshop will concentrate only on Lexical Scoping. + * [1]: JavaScriptは他に、Global, `with`, `catch`, `eval`という4つのスコープを + 持っていますが、あまり使われることはないのでここでは省略します。 + * [2]: このワークショップはレキシカルスコープのみを取り扱います。 diff --git a/scopes/ja/solution.md b/scopes/ja/solution.md index 2a2b490..b05fd95 100644 --- a/scopes/ja/solution.md +++ b/scopes/ja/solution.md @@ -1,8 +1,8 @@ ---- -# Solution +# 模範解答 -For comparison, here is a possible solution, so you can compare notes: +あなたの解答と比べてみましょう。 ```js function foo() { @@ -10,6 +10,6 @@ function foo() { } ``` -# Next lesson +# 次のレッスン -Execute `$ADVENTURE_COMMAND` to move on to the next lesson: _Scope Chains_. +`$ADVENTURE_COMMAND`を実行し次のレッスン _Scope Chains_ に進みましょう。 From 3851ed5930d3e0dfbd7471e9e486ff89e375a2fb Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:25:08 +0900 Subject: [PATCH 05/16] Separated executable into own folder --- bin/scope-chains-closures | 3 +++ runner.js => index.js | 4 +--- package.json | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100755 bin/scope-chains-closures rename runner.js => index.js (89%) mode change 100755 => 100644 diff --git a/bin/scope-chains-closures b/bin/scope-chains-closures new file mode 100755 index 0000000..9bd62a7 --- /dev/null +++ b/bin/scope-chains-closures @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../index.js').execute(process.argv.slice(2)); diff --git a/runner.js b/index.js old mode 100755 new mode 100644 similarity index 89% rename from runner.js rename to index.js index 7f4a283..962307b --- a/runner.js +++ b/index.js @@ -1,5 +1,3 @@ -#!/usr/bin/env node - 'use strict'; var packageJson = require('./package.json'), @@ -27,4 +25,4 @@ var shop = adventure({ }); }) -shop.execute(process.argv.slice(2)); +module.exports = shop diff --git a/package.json b/package.json index 4099f56..f66cb98 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,11 @@ "author": "Jess Telford (http://jes.st)", "license": "MIT", "dependencies": { - "adventure": "^2.10.0", "adventure-verify": "^2.2.0", "babel-core": "^5.4.3", "escope": "^1.0.3", "estraverse": "^4.1.0", - "msee": "^0.1.1" + "msee": "^0.1.1", + "workshopper-adventure": "^4.0.4" } } From a169d90c1be4579816056bd8652e7187f14cb1f8 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 01:34:02 +0900 Subject: [PATCH 06/16] Removed msee dependency --- package.json | 1 - problem.js | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index f66cb98..7ff3a18 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "babel-core": "^5.4.3", "escope": "^1.0.3", "estraverse": "^4.1.0", - "msee": "^0.1.1", "workshopper-adventure": "^4.0.4" } } diff --git a/problem.js b/problem.js index b89d41c..23b0cd2 100644 --- a/problem.js +++ b/problem.js @@ -1,5 +1,4 @@ -var msee = require('msee'), - path = require('path'), +var path = require('path'), verify = require('adventure-verify'); module.exports = function(dir, testCorrect) { @@ -7,11 +6,8 @@ module.exports = function(dir, testCorrect) { var problem = { init: function (exercise) { ['problem', 'solution', 'pass', 'fail'].forEach(function(type) { - problem[type] = function () { - return msee.parseFile( - dir + '/' + exercise.lang + '/' + type + '.md', - {paragraphEnd: '\n\n'} - ); + problem[type] = { + file: path.join(dir, exercise.i18n.lang(), type + '.md') } }); }, From 27f265de18743473847242d58eb77b6d7a2b0caa Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:28:02 +0900 Subject: [PATCH 07/16] Moved name from to setup instead of having a title in every exercises index.js --- exercises/garbage-collection/index.js | 1 - exercises/global-scope-and-shadowing/index.js | 1 - exercises/scope-chains/index.js | 1 - exercises/scopes/index.js | 1 - index.js | 35 +++++++++---------- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/exercises/garbage-collection/index.js b/exercises/garbage-collection/index.js index 3757829..4729577 100644 --- a/exercises/garbage-collection/index.js +++ b/exercises/garbage-collection/index.js @@ -1,7 +1,6 @@ var problem = require('../../problem'); module.exports = { - title: 'Garbage Collection', problem: problem(__dirname, function (args, t) { t.end(); }) diff --git a/exercises/global-scope-and-shadowing/index.js b/exercises/global-scope-and-shadowing/index.js index 6ef6deb..774c712 100644 --- a/exercises/global-scope-and-shadowing/index.js +++ b/exercises/global-scope-and-shadowing/index.js @@ -4,7 +4,6 @@ var fs = require('fs'), asciiScope = require('../../util/ascii-scope'); module.exports = { - title: 'Global Scope & Shadowing', problem: problem(__dirname, function (args, t) { var file = path.resolve(args[0]); diff --git a/exercises/scope-chains/index.js b/exercises/scope-chains/index.js index 6ae0858..f74f9c3 100644 --- a/exercises/scope-chains/index.js +++ b/exercises/scope-chains/index.js @@ -4,7 +4,6 @@ var fs = require('fs'), asciiScope = require('../../util/ascii-scope'); module.exports = { - title: 'Scope Chains', problem: problem(__dirname, function (args, t) { var file = path.resolve(args[0]); diff --git a/exercises/scopes/index.js b/exercises/scopes/index.js index c72c869..f0f96a8 100644 --- a/exercises/scopes/index.js +++ b/exercises/scopes/index.js @@ -4,7 +4,6 @@ var fs = require('fs'), asciiScope = require('../../util/ascii-scope'); module.exports = { - title: 'Scopes', problem: problem(__dirname, function (args, t) { var file = path.resolve(args[0]); diff --git a/index.js b/index.js index 962307b..4d4f1fb 100644 --- a/index.js +++ b/index.js @@ -4,25 +4,22 @@ adventure = require('workshopper-adventure/adventure'); var shop = adventure({ - name: packageJson.name, - appDir: __dirname, - languages: ['en', 'ja'] -}), - lesson; - -[ - 'scopes', - 'scope-chains', - 'global-scope-and-shadowing', - 'closures', - 'garbage-collection' -].forEach(function(lesson, index) { - - lesson = require('./exercises/' + lesson); - - shop.add((index + 1) + '. ' + lesson.title, function() { - return lesson.problem - }); + name: packageJson.name, + appDir: __dirname, + languages: ['en', 'ja'] }) + +;[ + 'Scopes', + 'Scope Chains', + 'Global Scope & Shadowing', + 'Closures', + 'Garbage Collection' +].forEach(function(name, index) { + shop.add((index + 1) + '. ' + name, function() { + var folder = name.replace(/\s/ig, '-').replace(/\&/ig, 'and') + return require('./' + folder).problem + }); + }) module.exports = shop From 89b1f6b46cc03a0fe856ad724928b38ca17ef5fb Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:29:19 +0900 Subject: [PATCH 08/16] Removed unnecessary packageJson reference (workshopped-adventure will take it automatically) --- index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index 4d4f1fb..5e0967b 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,10 @@ 'use strict'; - var packageJson = require('./package.json'), - adventure = require('workshopper-adventure/adventure'); - +var adventure = require('workshopper-adventure/adventure'); + var shop = adventure({ - name: packageJson.name, - appDir: __dirname, - languages: ['en', 'ja'] + appDir: __dirname, + languages: ['en', 'ja'] }) ;[ From 2f9087efc3aa36ca282a281709b67ef025a7b803 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 01:39:16 +0900 Subject: [PATCH 09/16] Changed repository specification to have the proper repo being shown in the help --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ff3a18..e48c505 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ }, "engineStrict": true, "preferGlobal": true, - "repository": "jesstelford/scope-chains-closures", + "repository": { + "type": "git", + "url": "https://github.com/jesstelford/scope-chains-closures.git" + }, "bugs": "https://github.com/jesstelford/scope-chains-closures/issues", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" From 4a32ff023ae6110d4a66e1865532016b3fef7ff9 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:31:14 +0900 Subject: [PATCH 10/16] Removed line breaks --- closures/ja/problem.md | 19 ++------ exercises/closures/en/problem.md | 20 ++------ exercises/garbage-collection/en/fail.md | 3 +- exercises/garbage-collection/en/problem.md | 41 ++++------------ exercises/garbage-collection/en/solution.md | 3 +- .../global-scope-and-shadowing/en/problem.md | 47 +++++-------------- exercises/scope-chains/en/problem.md | 23 +++------ exercises/scope-chains/en/solution.md | 3 +- exercises/scopes/en/problem.md | 26 ++++------ garbage-collection/ja/fail.md | 3 +- garbage-collection/ja/problem.md | 41 ++++------------ garbage-collection/ja/solution.md | 3 +- global-scope-and-shadowing/ja/problem.md | 47 +++++-------------- scope-chains/ja/problem.md | 23 +++------ scope-chains/ja/solution.md | 3 +- scopes/ja/problem.md | 11 ++--- 16 files changed, 84 insertions(+), 232 deletions(-) diff --git a/closures/ja/problem.md b/closures/ja/problem.md index 2dff9c0..549992f 100644 --- a/closures/ja/problem.md +++ b/closures/ja/problem.md @@ -1,8 +1,6 @@ # Closures -Closures are an important part of the Javascript language. They are what enables -the callback-last programming most prominent in node, and provide an excellent -mechanism for handling the asynchronous nature of most Javascript tasks. +Closures are an important part of the Javascript language. They are what enables the callback-last programming most prominent in node, and provide an excellent mechanism for handling the asynchronous nature of most Javascript tasks. To properly understand closures, let's start with an example scope chain: @@ -25,9 +23,7 @@ someFunc() ⋮ ``` -Given how nesting scope works, it's possible for an inner scope within -`someFunc()` to access `bar`. In this example, let's say `inner()` accesses -`bar`: +Given how nesting scope works, it's possible for an inner scope within `someFunc()` to access `bar`. In this example, let's say `inner()` accesses `bar`: ``` someFunc() @@ -42,17 +38,12 @@ alert(bar) Then `inner()` is said to _Close Over_ `bar`. Therefore `inner()` is a _Closure_. -To power the callback style of programming, the closure will be maintained even -if `inner()` isn't executed immediately. It is perfectly legal in Javascript to -pass `inner` around / return it from `someFunc()` for later execution. All the -while, `bar` will continue to be available. +To power the callback style of programming, the closure will be maintained even if `inner()` isn't executed immediately. It is perfectly legal in Javascript to pass `inner` around / return it from `someFunc()` for later execution. All the while, `bar` will continue to be available. ---- # Your Mission -Modify your solution from the previous lesson to set `bar = true` inside `zip()`, -then return the function `zip` as the result of `foo()` +Modify your solution from the previous lesson to set `bar = true` inside `zip()`, then return the function `zip` as the result of `foo()` -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/exercises/closures/en/problem.md b/exercises/closures/en/problem.md index 2dff9c0..9595bc9 100644 --- a/exercises/closures/en/problem.md +++ b/exercises/closures/en/problem.md @@ -1,8 +1,5 @@ # Closures - -Closures are an important part of the Javascript language. They are what enables -the callback-last programming most prominent in node, and provide an excellent -mechanism for handling the asynchronous nature of most Javascript tasks. +Closures are an important part of the Javascript language. They are what enables the callback-last programming most prominent in node, and provide an excellent mechanism for handling the asynchronous nature of most Javascript tasks. To properly understand closures, let's start with an example scope chain: @@ -25,9 +22,7 @@ someFunc() ⋮ ``` -Given how nesting scope works, it's possible for an inner scope within -`someFunc()` to access `bar`. In this example, let's say `inner()` accesses -`bar`: +Given how nesting scope works, it's possible for an inner scope within `someFunc()` to access `bar`. In this example, let's say `inner()` accesses `bar`: ``` someFunc() @@ -42,17 +37,12 @@ alert(bar) Then `inner()` is said to _Close Over_ `bar`. Therefore `inner()` is a _Closure_. -To power the callback style of programming, the closure will be maintained even -if `inner()` isn't executed immediately. It is perfectly legal in Javascript to -pass `inner` around / return it from `someFunc()` for later execution. All the -while, `bar` will continue to be available. +To power the callback style of programming, the closure will be maintained even if `inner()` isn't executed immediately. It is perfectly legal in Javascript to pass `inner` around / return it from `someFunc()` for later execution. All the while, `bar` will continue to be available. ---- # Your Mission -Modify your solution from the previous lesson to set `bar = true` inside `zip()`, -then return the function `zip` as the result of `foo()` +Modify your solution from the previous lesson to set `bar = true` inside `zip()`, then return the function `zip` as the result of `foo()` -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/exercises/garbage-collection/en/fail.md b/exercises/garbage-collection/en/fail.md index b30f303..fb0e750 100644 --- a/exercises/garbage-collection/en/fail.md +++ b/exercises/garbage-collection/en/fail.md @@ -1,7 +1,6 @@ # Unknown error..? -Congratulations! If you've made it to this screen, you deserve a nyan cat as a -reward :D +Congratulations! If you've made it to this screen, you deserve a nyan cat as a reward :D ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄░░░░░░░░░ diff --git a/exercises/garbage-collection/en/problem.md b/exercises/garbage-collection/en/problem.md index b9e6193..9994962 100644 --- a/exercises/garbage-collection/en/problem.md +++ b/exercises/garbage-collection/en/problem.md @@ -1,14 +1,7 @@ # Garbage Collection +Memory in Javascript is managed automatically by the runtime. The runtime decides when/if to release any allocated memory. This decision process is called _Garbage Collection_. -Memory in Javascript is managed automatically by the runtime. The runtime -decides when/if to release any allocated memory. This decision process is called -_Garbage Collection_. - -Every javascript runtime has their own algorithm for garbage collection, but -most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by -marking references to memory (variables, functions, etc) which are still -reachable from active code. Any reference which is not marked, is swept into -the garbage (i.e. the memory is freed). +Every javascript runtime has their own algorithm for garbage collection, but most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by marking references to memory (variables, functions, etc) which are still reachable from active code. Any reference which is not marked, is swept into the garbage (i.e. the memory is freed). This concept of marking reachable memory is particulary relevant to closures: @@ -24,29 +17,19 @@ return inner ⋮ ``` -When the closure `inner()` is returned from `someFunc()`, it maintains its -reference to `bar`. The Mark & Sweep algorithm will mark `bar` as reachable, and -hence will _not_ garbage collect it. +When the closure `inner()` is returned from `someFunc()`, it maintains its reference to `bar`. The Mark & Sweep algorithm will mark `bar` as reachable, and hence will _not_ garbage collect it. -For `inner()` to correctly resolve its reference to `bar`, not only does the -memory for `bar` need to be kept, but the scope chain which describes how to -reach `bar` must also be kept. +For `inner()` to correctly resolve its reference to `bar`, not only does the memory for `bar` need to be kept, but the scope chain which describes how to reach `bar` must also be kept. -Once the reference to `inner()` is no longer required, it can be marked for -garbage collection, which in turn means `bar` can also be marked, and finally -the entire scope chain can be marked, resulting in the freeing of all the -memory. +Once the reference to `inner()` is no longer required, it can be marked for garbage collection, which in turn means `bar` can also be marked, and finally the entire scope chain can be marked, resulting in the freeing of all the memory. -In this way, Scope, Scope Chains, Closures, and Garbage Collection are all -closely related. +In this way, Scope, Scope Chains, Closures, and Garbage Collection are all closely related. ---- # Your Mission -In this challenge, you will be required to use Chrome DevTools for detecting -Garbage Collection events. Follow these steps to get a feel for what happens -when Chrome performs its Mark & Sweep algorithm: +In this challenge, you will be required to use Chrome DevTools for detecting Garbage Collection events. Follow these steps to get a feel for what happens when Chrome performs its Mark & Sweep algorithm: 1) Fire up a new tab in Chrome 2) Open the DevTools > Timeline tab @@ -65,12 +48,6 @@ when Chrome performs its Mark & Sweep algorithm: 11) Clicking this event will reveal information about total memory garbage collected, and how long it took. -One particularly interesting thing of note here is the length of time Garbage -Collection can take: Often well beyond the 16ms maximum required to keep it -within a single frame (at 60fps). While garbage collection occurs, it blocks the -main thread, which means other Javascript cannot be executed until the event -completes. Be conscious of how janky your application may become due to -extensive Garbage Collection events! +One particularly interesting thing of note here is the length of time Garbage Collection can take: Often well beyond the 16ms maximum required to keep it within a single frame (at 60fps). While garbage collection occurs, it blocks the main thread, which means other Javascript cannot be executed until the event completes. Be conscious of how janky your application may become due to extensive Garbage Collection events! -**Note**: If you'd like to get that lovely `[COMPLETED]` label for this lesson, -Run `$ADVENTURE_COMMAND verify` +**Note**: If you'd like to get that lovely `[COMPLETED]` label for this lesson, Run `$ADVENTURE_COMMAND verify` diff --git a/exercises/garbage-collection/en/solution.md b/exercises/garbage-collection/en/solution.md index 19aeb35..96c4607 100644 --- a/exercises/garbage-collection/en/solution.md +++ b/exercises/garbage-collection/en/solution.md @@ -2,5 +2,4 @@ # Congratulations! -Now that you know all about Scope Chains, Closures, & Garbage Collection, why -not tweet about it: `http://bit.ly/sccjs-twitter-share` +Now that you know all about Scope Chains, Closures, & Garbage Collection, why not tweet about it: `http://bit.ly/sccjs-twitter-share` diff --git a/exercises/global-scope-and-shadowing/en/problem.md b/exercises/global-scope-and-shadowing/en/problem.md index 603caea..c209a8f 100644 --- a/exercises/global-scope-and-shadowing/en/problem.md +++ b/exercises/global-scope-and-shadowing/en/problem.md @@ -2,9 +2,7 @@ ## Global Scope -Understanding where Scope Chains end is an important part of scoping. All -Javascript runtimes must implicitly create a _Global Scope_ object (`window` in -the browser, `global` in node), which sits at the top of every scope chain: +Understanding where Scope Chains end is an important part of scoping. All Javascript runtimes must implicitly create a _Global Scope_ object (`window` in the browser, `global` in node), which sits at the top of every scope chain: ``` (global) @@ -21,9 +19,7 @@ inner() inner2() foo() ``` -In _Scopes_ we covered how usage of `var` or `let` dictates the scope of the -variable being defined. When assigning a variable without using either of `var`, -`let`, etc, the variable is assumed to exist in an outer scope. +In _Scopes_ we covered how usage of `var` or `let` dictates the scope of the variable being defined. When assigning a variable without using either of `var`, `let`, etc, the variable is assumed to exist in an outer scope. The javascript runtime follows these steps to assign a variable: @@ -49,28 +45,18 @@ function someFunc() { } ``` -Note the lack of `var` or `let`, etc for `foo = 2`. The Javascript runtime will -follow the above algorithm, first checking the scope of `inner()`, then of -`someFunc()`, then finally the Global Scope. Step 5 is then executed, so `foo` -becomes a variable in the Global Scope (`window.foo` / `global.foo`). +Note the lack of `var` or `let`, etc for `foo = 2`. The Javascript runtime will follow the above algorithm, first checking the scope of `inner()`, then of `someFunc()`, then finally the Global Scope. Step 5 is then executed, so `foo` becomes a variable in the Global Scope (`window.foo` / `global.foo`). -Phrased another way: By accidentally forgetting to use `var`, the variable `foo` -which otherwise would have been only within the lexical scope of `inner()` is -now available to be modified by _any_ scope. So, `someFunc()` now has access -where the developer may have meant for it not to. +Phrased another way: By accidentally forgetting to use `var`, the variable `foo` which otherwise would have been only within the lexical scope of `inner()` is +now available to be modified by _any_ scope. So, `someFunc()` now has access where the developer may have meant for it not to. -_Remember: Only inner scopes can access variables of outer scopes. In this case -the `someFunc()` scope is an inner scope of the Global Scope, allowing access of -`foo` to `someFunc()`._ +_Remember: Only inner scopes can access variables of outer scopes. In this case the `someFunc()` scope is an inner scope of the Global Scope, allowing access of `foo` to `someFunc()`._ ## Shadowing -A variable is created in a 'Step 0)' of the above algorithm: When `var` or `let` -is used. The variable is assigned to the correct scope, then execution moves on, -and any assignments to that variable follow the above algorithm. +A variable is created in a 'Step 0)' of the above algorithm: When `var` or `let` is used. The variable is assigned to the correct scope, then execution moves on, and any assignments to that variable follow the above algorithm. -It is perfectly valid to define two different variables, in different scopes, -with the same name: +It is perfectly valid to define two different variables, in different scopes, with the same name: ```js function someFunc() { @@ -92,24 +78,17 @@ function someFunc() { } ``` -This is called _Shadowing_. The `foo` inside `inner()` is said to _Shadow_ the `foo` -inside `someFunc`. +This is called _Shadowing_. The `foo` inside `inner()` is said to _Shadow_ the `foo` inside `someFunc`. -Shadowing means that the `inner()` scope only has access to its own `foo`. There -is no way for it to access the `foo` defined in `someFunc()`. +Shadowing means that the `inner()` scope only has access to its own `foo`. There is no way for it to access the `foo` defined in `someFunc()`. -This can also be an accidental source of bugs, especially when there is deep -nesting, or long functions. +This can also be an accidental source of bugs, especially when there is deep nesting, or long functions. ---- # Your Mission -Starting with your solution from the previous lesson, assign a value to the global variable -`quux` inside `foo()` (don't use `var` or `let`). Create a shadow variable in of `quux` -inside `zip()`. The value in the global variable `quux` has to be different than the -value of `quux` inside `zip()`. +Starting with your solution from the previous lesson, assign a value to the global variable `quux` inside `foo()` (don't use `var` or `let`). Create a shadow variable in of `quux` inside `zip()`. The value in the global variable `quux` has to be different than the value of `quux` inside `zip()`. -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/exercises/scope-chains/en/problem.md b/exercises/scope-chains/en/problem.md index f5cf54d..10b8b3a 100644 --- a/exercises/scope-chains/en/problem.md +++ b/exercises/scope-chains/en/problem.md @@ -36,8 +36,7 @@ function someFunc() { ## Scoped Variable Access -All nested scopes follow the same rule: Each nested inner scope has access to -outer scope variables, but *NOT* vice-versa. +All nested scopes follow the same rule: Each nested inner scope has access to outer scope variables, but *NOT* vice-versa. For example: @@ -54,10 +53,7 @@ access to `outerVar`* ## Multiple Nested Scopes -Nesting isn't limited to a single inner scope, there can be multiple nested -scopes, each of which adhere to the *Scoped Variable Access* rule above. With -one addition: sibling scopes are also restricted from accessing each other's -variables. +Nesting isn't limited to a single inner scope, there can be multiple nested scopes, each of which adhere to the *Scoped Variable Access* rule above. With one addition: sibling scopes are also restricted from accessing each other's variables. For example: ```js @@ -68,9 +64,7 @@ function someFunc() { } } ``` -*`inner` & `inner2` are both inner scopes of `someFunc`. Just as `someFunc` -cannot access `inner`'s variables, `inner` cannot access `inner2`'s variables -(and vice versa)* +*`inner` & `inner2` are both inner scopes of `someFunc`. Just as `someFunc` cannot access `inner`'s variables, `inner` cannot access `inner2`'s variables (and vice versa)* ## Scope Tree @@ -102,10 +96,7 @@ inner() inner2() foo() ``` -Remembering that inner scopes can access outer scope's variables, but *not* -vice-versa (`foo()` can access `inner2()`'s variables, and `inner2()` can access -`someFunc()`'s variables), then it makes more sense to look at the tree from -bottom-up, which forms a chain, also known as... +Remembering that inner scopes can access outer scope's variables, but *not* vice-versa (`foo()` can access `inner2()`'s variables, and `inner2()` can access `someFunc()`'s variables), then it makes more sense to look at the tree from bottom-up, which forms a chain, also known as... ## Scope Chains @@ -128,8 +119,6 @@ Looking from most inner to most outer scope forms a *Scope Chain*. # Your Mission -Modify your solution from lesson 1 so `foo` contains a function `zip` -which itself contains one variable lexically scoped called `quux` +Modify your solution from lesson 1 so `foo` contains a function `zip` which itself contains one variable lexically scoped called `quux` -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/exercises/scope-chains/en/solution.md b/exercises/scope-chains/en/solution.md index caa1d0f..f6b717e 100644 --- a/exercises/scope-chains/en/solution.md +++ b/exercises/scope-chains/en/solution.md @@ -16,8 +16,7 @@ The scope chain you created now looks like this: var quux ``` -By following the arrows, we can see `zip()` has access to `var bar`, but not the -other way around. +By following the arrows, we can see `zip()` has access to `var bar`, but not the other way around. ---- diff --git a/exercises/scopes/en/problem.md b/exercises/scopes/en/problem.md index c4f4d46..7cb12cf 100644 --- a/exercises/scopes/en/problem.md +++ b/exercises/scopes/en/problem.md @@ -1,20 +1,14 @@ # Scope Chains And Closures Workshop -Scope, Scope Chains, Closures, and Garbage Collection all have one thing in -common: They're often hand-waved away. How do closures actually work? When does -Garbage Collection occur? What really IS a Scope Chain? +Scope, Scope Chains, Closures, and Garbage Collection all have one thing in common: They're often hand-waved away. How do closures actually work? When does Garbage Collection occur? What really IS a Scope Chain? -In this workshop, we will discover it's not black magic after all; No hand -waving is required to explain these language features, in fact you've been using -them all along without realising. +In this workshop, we will discover it's not black magic after all; No hand waving is required to explain these language features, in fact you've been using them all along without realising. ---- -# Scopes +## Scopes -The main type of scope in Javascript is Lexical Scoping. Present in the language -from the very beginning, this is the scope created within a function, and the -one most developers are familiar with.[1] +The main type of scope in Javascript is Lexical Scoping. Present in the language from the very beginning, this is the scope created within a function, and the one most developers are familiar with.[1] ES6 recently defined Block Scoping. This scope is created within curly braced blocks.[2] @@ -38,8 +32,7 @@ function someFunc() { ### Block Scope -`let` & `const` are used to denote variables which are Block Scoped to the -current curly braced block: +`let` & `const` are used to denote variables which are Block Scoped to the current curly braced block: ```js if (true) { @@ -53,14 +46,11 @@ if (true) { # Your Mission -In an empty file, create a function `foo` which contains one variable lexically -scoped named `bar`. +In an empty file, create a function `foo` which contains one variable lexically scoped named `bar`. -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. ## Notes - * [1]: There are also 4 other scopes in the language: Global, `with`, `catch`, - and `eval`. These tend not to be used much, so we will ignore them. + * [1]: There are also 4 other scopes in the language: Global, `with`, `catch`, and `eval`. These tend not to be used much, so we will ignore them. * [2]: This workshop will concentrate only on Lexical Scoping. diff --git a/garbage-collection/ja/fail.md b/garbage-collection/ja/fail.md index b30f303..fb0e750 100644 --- a/garbage-collection/ja/fail.md +++ b/garbage-collection/ja/fail.md @@ -1,7 +1,6 @@ # Unknown error..? -Congratulations! If you've made it to this screen, you deserve a nyan cat as a -reward :D +Congratulations! If you've made it to this screen, you deserve a nyan cat as a reward :D ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄░░░░░░░░░ diff --git a/garbage-collection/ja/problem.md b/garbage-collection/ja/problem.md index b9e6193..9994962 100644 --- a/garbage-collection/ja/problem.md +++ b/garbage-collection/ja/problem.md @@ -1,14 +1,7 @@ # Garbage Collection +Memory in Javascript is managed automatically by the runtime. The runtime decides when/if to release any allocated memory. This decision process is called _Garbage Collection_. -Memory in Javascript is managed automatically by the runtime. The runtime -decides when/if to release any allocated memory. This decision process is called -_Garbage Collection_. - -Every javascript runtime has their own algorithm for garbage collection, but -most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by -marking references to memory (variables, functions, etc) which are still -reachable from active code. Any reference which is not marked, is swept into -the garbage (i.e. the memory is freed). +Every javascript runtime has their own algorithm for garbage collection, but most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by marking references to memory (variables, functions, etc) which are still reachable from active code. Any reference which is not marked, is swept into the garbage (i.e. the memory is freed). This concept of marking reachable memory is particulary relevant to closures: @@ -24,29 +17,19 @@ return inner ⋮ ``` -When the closure `inner()` is returned from `someFunc()`, it maintains its -reference to `bar`. The Mark & Sweep algorithm will mark `bar` as reachable, and -hence will _not_ garbage collect it. +When the closure `inner()` is returned from `someFunc()`, it maintains its reference to `bar`. The Mark & Sweep algorithm will mark `bar` as reachable, and hence will _not_ garbage collect it. -For `inner()` to correctly resolve its reference to `bar`, not only does the -memory for `bar` need to be kept, but the scope chain which describes how to -reach `bar` must also be kept. +For `inner()` to correctly resolve its reference to `bar`, not only does the memory for `bar` need to be kept, but the scope chain which describes how to reach `bar` must also be kept. -Once the reference to `inner()` is no longer required, it can be marked for -garbage collection, which in turn means `bar` can also be marked, and finally -the entire scope chain can be marked, resulting in the freeing of all the -memory. +Once the reference to `inner()` is no longer required, it can be marked for garbage collection, which in turn means `bar` can also be marked, and finally the entire scope chain can be marked, resulting in the freeing of all the memory. -In this way, Scope, Scope Chains, Closures, and Garbage Collection are all -closely related. +In this way, Scope, Scope Chains, Closures, and Garbage Collection are all closely related. ---- # Your Mission -In this challenge, you will be required to use Chrome DevTools for detecting -Garbage Collection events. Follow these steps to get a feel for what happens -when Chrome performs its Mark & Sweep algorithm: +In this challenge, you will be required to use Chrome DevTools for detecting Garbage Collection events. Follow these steps to get a feel for what happens when Chrome performs its Mark & Sweep algorithm: 1) Fire up a new tab in Chrome 2) Open the DevTools > Timeline tab @@ -65,12 +48,6 @@ when Chrome performs its Mark & Sweep algorithm: 11) Clicking this event will reveal information about total memory garbage collected, and how long it took. -One particularly interesting thing of note here is the length of time Garbage -Collection can take: Often well beyond the 16ms maximum required to keep it -within a single frame (at 60fps). While garbage collection occurs, it blocks the -main thread, which means other Javascript cannot be executed until the event -completes. Be conscious of how janky your application may become due to -extensive Garbage Collection events! +One particularly interesting thing of note here is the length of time Garbage Collection can take: Often well beyond the 16ms maximum required to keep it within a single frame (at 60fps). While garbage collection occurs, it blocks the main thread, which means other Javascript cannot be executed until the event completes. Be conscious of how janky your application may become due to extensive Garbage Collection events! -**Note**: If you'd like to get that lovely `[COMPLETED]` label for this lesson, -Run `$ADVENTURE_COMMAND verify` +**Note**: If you'd like to get that lovely `[COMPLETED]` label for this lesson, Run `$ADVENTURE_COMMAND verify` diff --git a/garbage-collection/ja/solution.md b/garbage-collection/ja/solution.md index 19aeb35..96c4607 100644 --- a/garbage-collection/ja/solution.md +++ b/garbage-collection/ja/solution.md @@ -2,5 +2,4 @@ # Congratulations! -Now that you know all about Scope Chains, Closures, & Garbage Collection, why -not tweet about it: `http://bit.ly/sccjs-twitter-share` +Now that you know all about Scope Chains, Closures, & Garbage Collection, why not tweet about it: `http://bit.ly/sccjs-twitter-share` diff --git a/global-scope-and-shadowing/ja/problem.md b/global-scope-and-shadowing/ja/problem.md index 9614d09..92cc9d3 100644 --- a/global-scope-and-shadowing/ja/problem.md +++ b/global-scope-and-shadowing/ja/problem.md @@ -2,9 +2,7 @@ ## Global Scope -Understanding where Scope Chains end is an important part of scoping. All -Javascript runtimes must implicitly create a _Global Scope_ object (`window` in -the browser, `global` in node), which sits at the top of every scope chain: +Understanding where Scope Chains end is an important part of scoping. All Javascript runtimes must implicitly create a _Global Scope_ object (`window` in the browser, `global` in node), which sits at the top of every scope chain: ``` (global) @@ -21,9 +19,7 @@ inner() inner2() foo() ``` -In _Scopes_ we covered how usage of `var` or `let` dictates the scope of the -variable being defined. When assigning a variable without using either of `var`, -`let`, etc, the variable is assumed to exist in an outer scope. +In _Scopes_ we covered how usage of `var` or `let` dictates the scope of the variable being defined. When assigning a variable without using either of `var`, `let`, etc, the variable is assumed to exist in an outer scope. The javascript runtime follows these steps to assign a variable: @@ -49,28 +45,18 @@ function someFunc() { } ``` -Note the lack of `var` or `let`, etc for `foo = 2`. The Javascript runtime will -follow the above algorithm, first checking the scope of `inner()`, then of -`someFunc()`, then finally the Global Scope. Step 5 is then executed, so `foo` -becomes a variable in the Global Scope (`window.foo` / `global.foo`). +Note the lack of `var` or `let`, etc for `foo = 2`. The Javascript runtime will follow the above algorithm, first checking the scope of `inner()`, then of `someFunc()`, then finally the Global Scope. Step 5 is then executed, so `foo` becomes a variable in the Global Scope (`window.foo` / `global.foo`). -Phrased another way: By accidentally forgetting to use `var`, the variable `foo` -which otherwise would have been only within the lexical scope of `inner()` is -now available to be modified by _any_ scope. So, `someFunc()` now has access -where the developer may have meant for it not to. +Phrased another way: By accidentally forgetting to use `var`, the variable `foo` which otherwise would have been only within the lexical scope of `inner()` is +now available to be modified by _any_ scope. So, `someFunc()` now has access where the developer may have meant for it not to. -_Remember: Only inner scopes can access variables of outer scopes. In this case -the `someFunc()` scope is an inner scope of the Global Scope, allowing access of -`foo` to `someFunc()`._ +_Remember: Only inner scopes can access variables of outer scopes. In this case the `someFunc()` scope is an inner scope of the Global Scope, allowing access of `foo` to `someFunc()`._ ## Shadowing -A variable is created in a 'Step 0)' of the above algorithm: When `var` or `let` -is used. The variable is assigned to the correct scope, then execution moves on, -and any assignments to that variable follow the above algorithm. +A variable is created in a 'Step 0)' of the above algorithm: When `var` or `let` is used. The variable is assigned to the correct scope, then execution moves on, and any assignments to that variable follow the above algorithm. -It is perfectly valid to define two different variables, in different scopes, -with the same name: +It is perfectly valid to define two different variables, in different scopes, with the same name: ```js function someFunc() { @@ -92,23 +78,16 @@ function someFunc() { } ``` -This is called _Shadowing_. The `foo` inside `inner()` is said to _Shadow_ the `foo` -inside `someFunc`. +This is called _Shadowing_. The `foo` inside `inner()` is said to _Shadow_ the `foo` inside `someFunc`. -Shadowing means that the `inner()` scope only has access to its own `foo`. There -is no way for it to access the `foo` defined in `someFunc()`. +Shadowing means that the `inner()` scope only has access to its own `foo`. There is no way for it to access the `foo` defined in `someFunc()`. -This can also be an accidental source of bugs, especially when there is deep -nesting, or long functions. +This can also be an accidental source of bugs, especially when there is deep nesting, or long functions. ---- # Your Mission -Starting with your solution from the previous lesson, assign a value to `quux` -inside `foo()` (don't use `var` or `let`). The value should be different to the -value assigned when defining `quux` inside `zip()`. - -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Starting with your solution from the previous lesson, assign a value to `quux` inside `foo()` (don't use `var` or `let`). The value should be different to the value assigned when defining `quux` inside `zip()`. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/scope-chains/ja/problem.md b/scope-chains/ja/problem.md index f5cf54d..10b8b3a 100644 --- a/scope-chains/ja/problem.md +++ b/scope-chains/ja/problem.md @@ -36,8 +36,7 @@ function someFunc() { ## Scoped Variable Access -All nested scopes follow the same rule: Each nested inner scope has access to -outer scope variables, but *NOT* vice-versa. +All nested scopes follow the same rule: Each nested inner scope has access to outer scope variables, but *NOT* vice-versa. For example: @@ -54,10 +53,7 @@ access to `outerVar`* ## Multiple Nested Scopes -Nesting isn't limited to a single inner scope, there can be multiple nested -scopes, each of which adhere to the *Scoped Variable Access* rule above. With -one addition: sibling scopes are also restricted from accessing each other's -variables. +Nesting isn't limited to a single inner scope, there can be multiple nested scopes, each of which adhere to the *Scoped Variable Access* rule above. With one addition: sibling scopes are also restricted from accessing each other's variables. For example: ```js @@ -68,9 +64,7 @@ function someFunc() { } } ``` -*`inner` & `inner2` are both inner scopes of `someFunc`. Just as `someFunc` -cannot access `inner`'s variables, `inner` cannot access `inner2`'s variables -(and vice versa)* +*`inner` & `inner2` are both inner scopes of `someFunc`. Just as `someFunc` cannot access `inner`'s variables, `inner` cannot access `inner2`'s variables (and vice versa)* ## Scope Tree @@ -102,10 +96,7 @@ inner() inner2() foo() ``` -Remembering that inner scopes can access outer scope's variables, but *not* -vice-versa (`foo()` can access `inner2()`'s variables, and `inner2()` can access -`someFunc()`'s variables), then it makes more sense to look at the tree from -bottom-up, which forms a chain, also known as... +Remembering that inner scopes can access outer scope's variables, but *not* vice-versa (`foo()` can access `inner2()`'s variables, and `inner2()` can access `someFunc()`'s variables), then it makes more sense to look at the tree from bottom-up, which forms a chain, also known as... ## Scope Chains @@ -128,8 +119,6 @@ Looking from most inner to most outer scope forms a *Scope Chain*. # Your Mission -Modify your solution from lesson 1 so `foo` contains a function `zip` -which itself contains one variable lexically scoped called `quux` +Modify your solution from lesson 1 so `foo` contains a function `zip` which itself contains one variable lexically scoped called `quux` -Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your -solution. +Once complete, execute `$ADVENTURE_COMMAND verify ` to verify your solution. diff --git a/scope-chains/ja/solution.md b/scope-chains/ja/solution.md index caa1d0f..f6b717e 100644 --- a/scope-chains/ja/solution.md +++ b/scope-chains/ja/solution.md @@ -16,8 +16,7 @@ The scope chain you created now looks like this: var quux ``` -By following the arrows, we can see `zip()` has access to `var bar`, but not the -other way around. +By following the arrows, we can see `zip()` has access to `var bar`, but not the other way around. ---- diff --git a/scopes/ja/problem.md b/scopes/ja/problem.md index a401a68..12ce460 100644 --- a/scopes/ja/problem.md +++ b/scopes/ja/problem.md @@ -5,15 +5,13 @@ クロージャは実際どう動いているの? ガーベジコレクションはいつ起動されるの? スコープチェーンっていったい何者? -実際誰も気づかない間に使っているこのあやふやなモノを -ワークショップを通してクリアにしていきましょう。 +実際誰も気づかない間に使っているこのあやふやなモノをワークショップを通してクリアにしていきましょう。 ---- # スコープ -JavaScriptでスコープといえば基本的に「レキシカルスコープ」になります。 -「関数」というスコープは初歩的であり開発者にとってはイメージしやすいでしょう。[1] +JavaScriptでスコープといえば基本的に「レキシカルスコープ」になります。「関数」というスコープは初歩的であり開発者にとってはイメージしやすいでしょう。[1] 最近、ES6では中括弧でスコープを定義する「ブロックスコープ」という概念も生まれました。[2] @@ -50,10 +48,9 @@ if (true) { # 課題 空ファイルの中に「レキシカルスコープ変数`bar`を持つ`foo`関数」を作りましょう。 -作り終えたら `$ADVENTURE_COMMAND verify ` を実行し答え合わせしましょう。 +作り終えたら `$ADVENTURE_COMMAND verify `を実行し答え合わせしましょう。 ## メモ - * [1]: JavaScriptは他に、Global, `with`, `catch`, `eval`という4つのスコープを - 持っていますが、あまり使われることはないのでここでは省略します。 + * [1]: JavaScriptは他に、Global, `with`, `catch`, `eval`という4つのスコープを持っていますが、あまり使われることはないのでここでは省略します。 * [2]: このワークショップはレキシカルスコープのみを取り扱います。 From 226f0bf313f819f0f7f7418f474220f884d591f7 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 01:54:25 +0900 Subject: [PATCH 11/16] Moved header declaration to header option of workshopper-adventure --- closures/ja/problem.md | 2 -- exercises/closures/en/problem.md | 1 - exercises/garbage-collection/en/problem.md | 1 - .../global-scope-and-shadowing/en/problem.md | 2 -- exercises/scope-chains/en/problem.md | 2 -- exercises/scopes/en/problem.md | 2 +- exercises/scopes/index.js | 30 ++++++++++--------- garbage-collection/ja/problem.md | 1 - global-scope-and-shadowing/ja/problem.md | 1 - index.js | 3 +- scope-chains/ja/problem.md | 2 -- scopes/ja/problem.md | 2 +- 12 files changed, 20 insertions(+), 29 deletions(-) diff --git a/closures/ja/problem.md b/closures/ja/problem.md index 549992f..9f3e2dd 100644 --- a/closures/ja/problem.md +++ b/closures/ja/problem.md @@ -1,5 +1,3 @@ -# Closures - Closures are an important part of the Javascript language. They are what enables the callback-last programming most prominent in node, and provide an excellent mechanism for handling the asynchronous nature of most Javascript tasks. To properly understand closures, let's start with an example scope chain: diff --git a/exercises/closures/en/problem.md b/exercises/closures/en/problem.md index 9595bc9..9f3e2dd 100644 --- a/exercises/closures/en/problem.md +++ b/exercises/closures/en/problem.md @@ -1,4 +1,3 @@ -# Closures Closures are an important part of the Javascript language. They are what enables the callback-last programming most prominent in node, and provide an excellent mechanism for handling the asynchronous nature of most Javascript tasks. To properly understand closures, let's start with an example scope chain: diff --git a/exercises/garbage-collection/en/problem.md b/exercises/garbage-collection/en/problem.md index 9994962..15d9059 100644 --- a/exercises/garbage-collection/en/problem.md +++ b/exercises/garbage-collection/en/problem.md @@ -1,4 +1,3 @@ -# Garbage Collection Memory in Javascript is managed automatically by the runtime. The runtime decides when/if to release any allocated memory. This decision process is called _Garbage Collection_. Every javascript runtime has their own algorithm for garbage collection, but most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by marking references to memory (variables, functions, etc) which are still reachable from active code. Any reference which is not marked, is swept into the garbage (i.e. the memory is freed). diff --git a/exercises/global-scope-and-shadowing/en/problem.md b/exercises/global-scope-and-shadowing/en/problem.md index c209a8f..d6af867 100644 --- a/exercises/global-scope-and-shadowing/en/problem.md +++ b/exercises/global-scope-and-shadowing/en/problem.md @@ -1,5 +1,3 @@ -# Global Scope & Shadowing - ## Global Scope Understanding where Scope Chains end is an important part of scoping. All Javascript runtimes must implicitly create a _Global Scope_ object (`window` in the browser, `global` in node), which sits at the top of every scope chain: diff --git a/exercises/scope-chains/en/problem.md b/exercises/scope-chains/en/problem.md index 10b8b3a..1003f96 100644 --- a/exercises/scope-chains/en/problem.md +++ b/exercises/scope-chains/en/problem.md @@ -1,5 +1,3 @@ -# Scope Chains - ## Nesting Scopes can be nested. Both Lexical and Block scopes can contain other scopes: diff --git a/exercises/scopes/en/problem.md b/exercises/scopes/en/problem.md index 7cb12cf..9871cfb 100644 --- a/exercises/scopes/en/problem.md +++ b/exercises/scopes/en/problem.md @@ -6,7 +6,7 @@ In this workshop, we will discover it's not black magic after all; No hand wavin ---- -## Scopes +## __{currentExercise.name}__ (_{progress.state_resolved}_) The main type of scope in Javascript is Lexical Scoping. Present in the language from the very beginning, this is the scope created within a function, and the one most developers are familiar with.[1] diff --git a/exercises/scopes/index.js b/exercises/scopes/index.js index f0f96a8..d1ce06e 100644 --- a/exercises/scopes/index.js +++ b/exercises/scopes/index.js @@ -3,26 +3,28 @@ var fs = require('fs'), problem = require('../../problem'), asciiScope = require('../../util/ascii-scope'); -module.exports = { - problem: problem(__dirname, function (args, t) { +var exercise = problem(__dirname, function (args, t) { + var file = path.resolve(args[0]); - var file = path.resolve(args[0]); + fs.readFile(file, function(err, code) { - fs.readFile(file, function(err, code) { + t.error(err, 'Solution loaded'); - t.error(err, 'Solution loaded'); + scopeAsAscii = asciiScope(code); - scopeAsAscii = asciiScope(code); + t.equal( + scopeAsAscii, + ['(global)','\tfoo()','\t- var bar'].join('\n'), + 'The structure is correct' + ); - t.equal( - scopeAsAscii, - ['(global)','\tfoo()','\t- var bar'].join('\n'), - 'The structure is correct' - ); + t.end(); - t.end(); + }); +}); - }); +exercise.header = ''; - }) +module.exports = { + problem: exercise } diff --git a/garbage-collection/ja/problem.md b/garbage-collection/ja/problem.md index 9994962..15d9059 100644 --- a/garbage-collection/ja/problem.md +++ b/garbage-collection/ja/problem.md @@ -1,4 +1,3 @@ -# Garbage Collection Memory in Javascript is managed automatically by the runtime. The runtime decides when/if to release any allocated memory. This decision process is called _Garbage Collection_. Every javascript runtime has their own algorithm for garbage collection, but most use a variation of Mark & Sweep. The Mark & Sweep algorithm works by marking references to memory (variables, functions, etc) which are still reachable from active code. Any reference which is not marked, is swept into the garbage (i.e. the memory is freed). diff --git a/global-scope-and-shadowing/ja/problem.md b/global-scope-and-shadowing/ja/problem.md index 92cc9d3..1425521 100644 --- a/global-scope-and-shadowing/ja/problem.md +++ b/global-scope-and-shadowing/ja/problem.md @@ -1,4 +1,3 @@ -# Global Scope & Shadowing ## Global Scope diff --git a/index.js b/index.js index 5e0967b..88255dc 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,8 @@ var adventure = require('workshopper-adventure/adventure'); var shop = adventure({ appDir: __dirname, - languages: ['en', 'ja'] + languages: ['en', 'ja'], + header: require('workshopper-adventure/default/header') }) ;[ diff --git a/scope-chains/ja/problem.md b/scope-chains/ja/problem.md index 10b8b3a..1003f96 100644 --- a/scope-chains/ja/problem.md +++ b/scope-chains/ja/problem.md @@ -1,5 +1,3 @@ -# Scope Chains - ## Nesting Scopes can be nested. Both Lexical and Block scopes can contain other scopes: diff --git a/scopes/ja/problem.md b/scopes/ja/problem.md index 12ce460..2816cd3 100644 --- a/scopes/ja/problem.md +++ b/scopes/ja/problem.md @@ -9,7 +9,7 @@ ---- -# スコープ +## __{currentExercise.name}__ (_{progress.state_resolved}_) JavaScriptでスコープといえば基本的に「レキシカルスコープ」になります。「関数」というスコープは初歩的であり開発者にとってはイメージしやすいでしょう。[1] From 00322cd50f09c51d82ea071d65768309d881e74c Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 01:56:15 +0900 Subject: [PATCH 12/16] Better footer separator --- index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 88255dc..1397d5d 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,11 @@ var adventure = require('workshopper-adventure/adventure'); var shop = adventure({ appDir: __dirname, languages: ['en', 'ja'], - header: require('workshopper-adventure/default/header') + header: require('workshopper-adventure/default/header'), + footer: [ + {text: '---', type: 'md'}, + require('workshopper-adventure/default/footer') + ] }) ;[ From 4fc15154ce1b82884bdec96447ce4643b5d6ac71 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 01:57:13 +0900 Subject: [PATCH 13/16] Removed number because the other workshoppers / adventures don't have numbers either --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 1397d5d..4cfa9ff 100644 --- a/index.js +++ b/index.js @@ -19,7 +19,7 @@ var shop = adventure({ 'Closures', 'Garbage Collection' ].forEach(function(name, index) { - shop.add((index + 1) + '. ' + name, function() { + shop.add(name, function() { var folder = name.replace(/\s/ig, '-').replace(/\&/ig, 'and') return require('./' + folder).problem }); From 800f913d24f47973e79c73548a003e5388d6d466 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:00:09 +0900 Subject: [PATCH 14/16] Fixed menu translation after number was removed --- i18n/ja.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ja.json b/i18n/ja.json index d692936..769de61 100644 --- a/i18n/ja.json +++ b/i18n/ja.json @@ -1,9 +1,9 @@ { "exercise": { - "1. Scopes": "1. Scopes", - "2. Scope Chains": "2. Scope Chains", - "3. Global Scope & Shadowing": "3. Global Scope & Shadowing", - "4. Closures": "4. Closures", - "5. Garbage Collection": "5. Garbage Collection" + "Scopes": "Scopes", + "Scope Chains": "Scope Chains", + "Global Scope & Shadowing": "Global Scope & Shadowing", + "Closures": "Closures", + "Garbage Collection": "Garbage Collection" } } \ No newline at end of file From 1309235f91fec0529c8c25b0e3e155d63659a286 Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:32:52 +0900 Subject: [PATCH 15/16] Added exercises that was lost somewhere in rebase --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 4cfa9ff..6d5205e 100644 --- a/index.js +++ b/index.js @@ -21,7 +21,7 @@ var shop = adventure({ ].forEach(function(name, index) { shop.add(name, function() { var folder = name.replace(/\s/ig, '-').replace(/\&/ig, 'and') - return require('./' + folder).problem + return require('./exercises/' + folder).problem }); }) From d05ec8d5f2cae5af1e2a4680bd71ca0cc966147e Mon Sep 17 00:00:00 2001 From: Martin Heidegger Date: Thu, 22 Oct 2015 02:34:54 +0900 Subject: [PATCH 16/16] Moved japanese files in correct order (was broken after rebase) --- {closures => exercises/closures}/ja/fail.md | 0 {closures => exercises/closures}/ja/pass.md | 0 {closures => exercises/closures}/ja/problem.md | 0 {closures => exercises/closures}/ja/solution.md | 0 {garbage-collection => exercises/garbage-collection}/ja/fail.md | 0 {garbage-collection => exercises/garbage-collection}/ja/pass.md | 0 .../garbage-collection}/ja/problem.md | 0 .../garbage-collection}/ja/solution.md | 0 .../global-scope-and-shadowing}/ja/fail.md | 0 .../global-scope-and-shadowing}/ja/pass.md | 0 .../global-scope-and-shadowing}/ja/problem.md | 0 .../global-scope-and-shadowing}/ja/solution.md | 0 {scope-chains => exercises/scope-chains}/ja/fail.md | 0 {scope-chains => exercises/scope-chains}/ja/pass.md | 0 {scope-chains => exercises/scope-chains}/ja/problem.md | 0 {scope-chains => exercises/scope-chains}/ja/solution.md | 0 {scopes => exercises/scopes}/ja/fail.md | 0 {scopes => exercises/scopes}/ja/pass.md | 0 {scopes => exercises/scopes}/ja/problem.md | 0 {scopes => exercises/scopes}/ja/solution.md | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename {closures => exercises/closures}/ja/fail.md (100%) rename {closures => exercises/closures}/ja/pass.md (100%) rename {closures => exercises/closures}/ja/problem.md (100%) rename {closures => exercises/closures}/ja/solution.md (100%) rename {garbage-collection => exercises/garbage-collection}/ja/fail.md (100%) rename {garbage-collection => exercises/garbage-collection}/ja/pass.md (100%) rename {garbage-collection => exercises/garbage-collection}/ja/problem.md (100%) rename {garbage-collection => exercises/garbage-collection}/ja/solution.md (100%) rename {global-scope-and-shadowing => exercises/global-scope-and-shadowing}/ja/fail.md (100%) rename {global-scope-and-shadowing => exercises/global-scope-and-shadowing}/ja/pass.md (100%) rename {global-scope-and-shadowing => exercises/global-scope-and-shadowing}/ja/problem.md (100%) rename {global-scope-and-shadowing => exercises/global-scope-and-shadowing}/ja/solution.md (100%) rename {scope-chains => exercises/scope-chains}/ja/fail.md (100%) rename {scope-chains => exercises/scope-chains}/ja/pass.md (100%) rename {scope-chains => exercises/scope-chains}/ja/problem.md (100%) rename {scope-chains => exercises/scope-chains}/ja/solution.md (100%) rename {scopes => exercises/scopes}/ja/fail.md (100%) rename {scopes => exercises/scopes}/ja/pass.md (100%) rename {scopes => exercises/scopes}/ja/problem.md (100%) rename {scopes => exercises/scopes}/ja/solution.md (100%) diff --git a/closures/ja/fail.md b/exercises/closures/ja/fail.md similarity index 100% rename from closures/ja/fail.md rename to exercises/closures/ja/fail.md diff --git a/closures/ja/pass.md b/exercises/closures/ja/pass.md similarity index 100% rename from closures/ja/pass.md rename to exercises/closures/ja/pass.md diff --git a/closures/ja/problem.md b/exercises/closures/ja/problem.md similarity index 100% rename from closures/ja/problem.md rename to exercises/closures/ja/problem.md diff --git a/closures/ja/solution.md b/exercises/closures/ja/solution.md similarity index 100% rename from closures/ja/solution.md rename to exercises/closures/ja/solution.md diff --git a/garbage-collection/ja/fail.md b/exercises/garbage-collection/ja/fail.md similarity index 100% rename from garbage-collection/ja/fail.md rename to exercises/garbage-collection/ja/fail.md diff --git a/garbage-collection/ja/pass.md b/exercises/garbage-collection/ja/pass.md similarity index 100% rename from garbage-collection/ja/pass.md rename to exercises/garbage-collection/ja/pass.md diff --git a/garbage-collection/ja/problem.md b/exercises/garbage-collection/ja/problem.md similarity index 100% rename from garbage-collection/ja/problem.md rename to exercises/garbage-collection/ja/problem.md diff --git a/garbage-collection/ja/solution.md b/exercises/garbage-collection/ja/solution.md similarity index 100% rename from garbage-collection/ja/solution.md rename to exercises/garbage-collection/ja/solution.md diff --git a/global-scope-and-shadowing/ja/fail.md b/exercises/global-scope-and-shadowing/ja/fail.md similarity index 100% rename from global-scope-and-shadowing/ja/fail.md rename to exercises/global-scope-and-shadowing/ja/fail.md diff --git a/global-scope-and-shadowing/ja/pass.md b/exercises/global-scope-and-shadowing/ja/pass.md similarity index 100% rename from global-scope-and-shadowing/ja/pass.md rename to exercises/global-scope-and-shadowing/ja/pass.md diff --git a/global-scope-and-shadowing/ja/problem.md b/exercises/global-scope-and-shadowing/ja/problem.md similarity index 100% rename from global-scope-and-shadowing/ja/problem.md rename to exercises/global-scope-and-shadowing/ja/problem.md diff --git a/global-scope-and-shadowing/ja/solution.md b/exercises/global-scope-and-shadowing/ja/solution.md similarity index 100% rename from global-scope-and-shadowing/ja/solution.md rename to exercises/global-scope-and-shadowing/ja/solution.md diff --git a/scope-chains/ja/fail.md b/exercises/scope-chains/ja/fail.md similarity index 100% rename from scope-chains/ja/fail.md rename to exercises/scope-chains/ja/fail.md diff --git a/scope-chains/ja/pass.md b/exercises/scope-chains/ja/pass.md similarity index 100% rename from scope-chains/ja/pass.md rename to exercises/scope-chains/ja/pass.md diff --git a/scope-chains/ja/problem.md b/exercises/scope-chains/ja/problem.md similarity index 100% rename from scope-chains/ja/problem.md rename to exercises/scope-chains/ja/problem.md diff --git a/scope-chains/ja/solution.md b/exercises/scope-chains/ja/solution.md similarity index 100% rename from scope-chains/ja/solution.md rename to exercises/scope-chains/ja/solution.md diff --git a/scopes/ja/fail.md b/exercises/scopes/ja/fail.md similarity index 100% rename from scopes/ja/fail.md rename to exercises/scopes/ja/fail.md diff --git a/scopes/ja/pass.md b/exercises/scopes/ja/pass.md similarity index 100% rename from scopes/ja/pass.md rename to exercises/scopes/ja/pass.md diff --git a/scopes/ja/problem.md b/exercises/scopes/ja/problem.md similarity index 100% rename from scopes/ja/problem.md rename to exercises/scopes/ja/problem.md diff --git a/scopes/ja/solution.md b/exercises/scopes/ja/solution.md similarity index 100% rename from scopes/ja/solution.md rename to exercises/scopes/ja/solution.md