diff --git a/1-js/04-object-basics/01-object/3-is-empty/solution.md b/1-js/04-object-basics/01-object/3-is-empty/solution.md index b3f40e3d..b876973b 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/solution.md +++ b/1-js/04-object-basics/01-object/3-is-empty/solution.md @@ -1,10 +1 @@ Just loop over the object and `return false` immediately if there's at least one property. - -```js -function isEmpty(obj) { - for (let key in obj) { - return false; - } - return true; -} -``` diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/solution.md b/1-js/04-object-basics/01-object/8-multiply-numeric/solution.md index e7edda60..e69de29b 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/solution.md +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/solution.md @@ -1,19 +0,0 @@ -``` js run - -// before the call -let menu = { - width: 200, - height: 300, - title: "My menu" -}; - -function multiplyNumeric(obj) { - for (let key in obj) { - if (typeof obj[key] == 'number') { - obj[key] *= 2; - } - } -} - -alert(menu); -``` diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md index 22c4bf18..45999762 100644 --- a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md +++ b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md @@ -1,6 +1,5 @@ - -```js run demo +```js run demo solution let calculator = { sum() { return this.a + this.b; @@ -20,4 +19,3 @@ calculator.read(); alert( calculator.sum() ); alert( calculator.mul() ); ``` - diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md index 41edd723..2b47873f 100644 --- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md +++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md @@ -1,6 +1,6 @@ The solution is to return the object itself from every call. -```js run +```js run demo let ladder = { step: 0, up() { @@ -28,7 +28,7 @@ ladder.up().up().down().up().down().showStep(); // 1 We also can write a single call per line. For long chains it's more readable: -```js +```js ladder .up() .up() @@ -37,4 +37,3 @@ ladder .down() .showStep(); // 1 ``` - diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md index e5583c5d..86bb6541 100644 --- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md +++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md @@ -1,5 +1,3 @@ - - ```js run demo function Calculator() { diff --git a/1-js/05-data-types/03-string/3-truncate/solution.md b/1-js/05-data-types/03-string/3-truncate/solution.md index a49b7090..5546c47e 100644 --- a/1-js/05-data-types/03-string/3-truncate/solution.md +++ b/1-js/05-data-types/03-string/3-truncate/solution.md @@ -2,10 +2,9 @@ The maximal length must be `maxlength`, so we need to cut it a little shorter, t Note that there is actually a single unicode character for an ellipsis. That's not three dots. -```js run +```js run demo function truncate(str, maxlength) { - return (str.length > maxlength) ? + return (str.length > maxlength) ? str.slice(0, maxlength - 1) + '…' : str; } ``` - diff --git a/1-js/05-data-types/03-string/4-extract-currency/solution.md b/1-js/05-data-types/03-string/4-extract-currency/solution.md index d9012677..e69de29b 100644 --- a/1-js/05-data-types/03-string/4-extract-currency/solution.md +++ b/1-js/05-data-types/03-string/4-extract-currency/solution.md @@ -1,5 +0,0 @@ -```js run - function extractCurrencyValue(str) { - return +str.slice(1); - } -``` diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md index 3b82e645..edf39289 100644 --- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md +++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md @@ -1,4 +1,4 @@ -# The slow solution +# Slow solution We can calculate all possible subsums. @@ -67,7 +67,7 @@ Let's walk the array and keep the current partial sum of elements in the variabl If the description is too vague, please see the code, it's short enough: -```js run +```js run demo function getMaxSubSum(arr) { let maxSum = 0; let partialSum = 0; diff --git a/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js b/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js index 024d6d6c..490f570a 100644 --- a/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js +++ b/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js @@ -1,8 +1,10 @@ function camelize(str) { return str - .split('-') // my-long-word -> ['my', 'long', 'word'] - .map( + .split('-') // splits 'my-long-word' into array ['my', 'long', 'word'] + .map( + // capitalizes first letters of all array items except the first one + // converts ['my', 'long', 'word'] into ['my', 'Long', 'Word'] (word, index) => index == 0 ? word : word[0].toUpperCase() + word.slice(1) - ) // ['my', 'long', 'word'] -> ['my', 'Long', 'Word'] - .join(''); // ['my', 'Long', 'Word'] -> myLongWord + ) + .join(''); // joins ['my', 'Long', 'Word'] into 'myLongWord' } diff --git a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md index 8f7fd9af..32d3b267 100644 --- a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md +++ b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md @@ -2,7 +2,7 @@ Let's walk the array items: - For each item we'll check if the resulting array already has that item. - If it is so, then ignore, otherwise add to results. -```js run +```js run demo function unique(arr) { let result = []; diff --git a/1-js/05-data-types/05-array-methods/2-filter-range/solution.md b/1-js/05-data-types/05-array-methods/2-filter-range/solution.md index 80b03078..73993a07 100644 --- a/1-js/05-data-types/05-array-methods/2-filter-range/solution.md +++ b/1-js/05-data-types/05-array-methods/2-filter-range/solution.md @@ -1,4 +1,4 @@ -``` js run +```js run demo function filterRange(arr, a, b) { // added brackets around the expression for better readability return arr.filter(item => (a <= item && item <= b)); diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js index 61cda126..488db375 100644 --- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js +++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js @@ -1,5 +1,4 @@ - function filterRangeInPlace(arr, a, b) { for (let i = 0; i < arr.length; i++) { @@ -12,4 +11,4 @@ function filterRangeInPlace(arr, a, b) { } } -} \ No newline at end of file +} diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md index ced9a9ac..36e3130f 100644 --- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md +++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md @@ -1,4 +1,4 @@ -``` js run +```js run demo function filterRangeInPlace(arr, a, b) { for (let i = 0; i < arr.length; i++) { @@ -18,5 +18,4 @@ let arr = [5, 3, 8, 1]; filterRangeInPlace(arr, 1, 4); // removed the numbers except from 1 to 4 alert( arr ); // [3, 1] - ``` diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md index 7ae86f4f..4c8af1f2 100644 --- a/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md +++ b/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md @@ -59,7 +59,7 @@ Here we could also use a plain object instead of the `Map`, because keys are str That's how the solution can look: -```js run +```js run demo function aclean(arr) { let obj = {}; diff --git a/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md b/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md index 4dff0e52..27a7b418 100644 --- a/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md +++ b/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md @@ -1,4 +1,4 @@ -```js run +```js run demo function sumSalaries(salaries) { let sum = 0; @@ -8,7 +8,22 @@ function sumSalaries(salaries) { return sum; // 650 } + +let salaries = { + "John": 100, + "Pete": 300, + "Mary": 250 +}; + +alert( sumSalaries(salaries) ); // 650 ``` Or, optionally, we could also get the sum using `Object.values` and `reduce`: -`Object.values(salaries).reduce((a, b) => a + b) // 650` +```js +// reduce loops over array of salaries, +// adding them up +// and returns the result +function sumSalaries(salaries) { + return Object.values(salaries).reduce((a, b) => a + b, 0) // 650 +} +``` diff --git a/1-js/05-data-types/10-date/2-get-week-day/solution.md b/1-js/05-data-types/10-date/2-get-week-day/solution.md index 2acaabf9..58d75c1c 100644 --- a/1-js/05-data-types/10-date/2-get-week-day/solution.md +++ b/1-js/05-data-types/10-date/2-get-week-day/solution.md @@ -2,7 +2,7 @@ The method `date.getDay()` returns the number of the weekday, starting from sund Let's make an array of weekdays, so that we can get the proper day name by its number: -```js run +```js run demo function getWeekDay(date) { let days = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']; diff --git a/1-js/05-data-types/10-date/3-weekday/solution.md b/1-js/05-data-types/10-date/3-weekday/solution.md index bfe3f4ca..e69de29b 100644 --- a/1-js/05-data-types/10-date/3-weekday/solution.md +++ b/1-js/05-data-types/10-date/3-weekday/solution.md @@ -1,14 +0,0 @@ -```js run -function getLocalDay(date) { - - let day = date.getDay(); - - if (day == 0) { // 0 becomes 7 - day = 7; - } - - return day; -} - -alert( getLocalDay(new Date(2012, 0, 3)) ); // 2 -``` diff --git a/1-js/05-data-types/10-date/4-get-date-ago/solution.md b/1-js/05-data-types/10-date/4-get-date-ago/solution.md index 7abc7ab9..5c394c10 100644 --- a/1-js/05-data-types/10-date/4-get-date-ago/solution.md +++ b/1-js/05-data-types/10-date/4-get-date-ago/solution.md @@ -11,7 +11,7 @@ function getDateAgo(date, days) { To implement it let's clone the date, like this: -```js run +```js run demo function getDateAgo(date, days) { let dateCopy = new Date(date); diff --git a/1-js/05-data-types/10-date/5-last-day-of-month/solution.md b/1-js/05-data-types/10-date/5-last-day-of-month/solution.md index 65f61c5b..4f642536 100644 --- a/1-js/05-data-types/10-date/5-last-day-of-month/solution.md +++ b/1-js/05-data-types/10-date/5-last-day-of-month/solution.md @@ -1,5 +1,5 @@ Let's create a date using the next month, but pass zero as the day: -```js run +```js run demo function getLastDayOfMonth(year, month) { let date = new Date(year, month + 1, 0); return date.getDate(); diff --git a/1-js/05-data-types/10-date/8-format-date-relative/solution.md b/1-js/05-data-types/10-date/8-format-date-relative/solution.md index 24fec997..2507c840 100644 --- a/1-js/05-data-types/10-date/8-format-date-relative/solution.md +++ b/1-js/05-data-types/10-date/8-format-date-relative/solution.md @@ -1,6 +1,6 @@ To get the time from `date` till now -- let's substract the dates. -```js run +```js run demo function formatDate(date) { let diff = new Date() - date; // the difference in milliseconds @@ -57,12 +57,12 @@ function formatDate(date) { let diffSec = Math.round(diffMs / 1000); let diffMin = diffSec / 60; let diffHour = diffMin / 60; - + // formatting year = year.toString().slice(-2); month = month < 10 ? '0' + month : month; dayOfMonth = dayOfMonth < 10 ? '0' + dayOfMonth : dayOfMonth; - + if (diffSec < 1) { return 'right now'; } else if (diffMin < 1) { diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md b/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md index 5bbc33b0..46c5514a 100644 --- a/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md +++ b/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md @@ -14,7 +14,7 @@ alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6 # Filter inArray -```js run +```js run demo function inArray(arr) { return function(x) { return arr.includes(x); diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md b/1-js/06-advanced-functions/03-closure/8-make-army/solution.md index 03c34b07..f5afd426 100644 --- a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md +++ b/1-js/06-advanced-functions/03-closure/8-make-army/solution.md @@ -55,9 +55,9 @@ function makeArmy() { As a result, all `shooter` functions get from the outer lexical envrironment the same, last value `i=10`. -The fix can be very simple: +We can fix it by moving the variable definition into the loop: -```js run +```js run demo function makeArmy() { let shooters = []; @@ -80,9 +80,9 @@ army[0](); // 0 army[5](); // 5 ``` -Now it works correctly, because every time the code block in `for (..) {...}` is executed, a new Lexical Environment is created for it, with the corresponding value of `i`. +Now it works correctly, because every time the code block in `for (let i=0...) {...}` is executed, a new Lexical Environment is created for it, with the corresponding variable `i`. -So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. A `shooter` gets the value exactly from the one where it was created. +So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. That's why now it works. ![](lexenv-makearmy.png) @@ -90,7 +90,6 @@ Here we rewrote `while` into `for`. Another trick could be possible, let's see it for better understanding of the subject: - ```js run function makeArmy() { let shooters = []; diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md index 44b5024e..24bb4d44 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md @@ -1,6 +1,6 @@ The solution: -```js +```js run demo function delay(f, ms) { return function() { @@ -8,20 +8,25 @@ function delay(f, ms) { }; } + +let f1000 = delay(alert, 1000); + +f1000("test"); // shows "test" after 1000ms ``` Please note how an arrow function is used here. As we know, arrow functions do not have own `this` and `arguments`, so `f.apply(this, arguments)` takes `this` and `arguments` from the wrapper. -If we pass a regular function, `setTimeout` would call it without arguments and `this=window` (in-browser), so we'd need to write a bit more code to pass them from the wrapper: +If we pass a regular function, `setTimeout` would call it without arguments and `this=window` (assuming we're in the browser). + +We still can pass the right `this` by using an intermediate variable, but that's a little bit more cumbersome: ```js function delay(f, ms) { - // added variables to pass this and arguments from the wrapper inside setTimeout return function(...args) { - let savedThis = this; + let savedThis = this; // store this into an intermediate variable setTimeout(function() { - f.apply(savedThis, args); + f.apply(savedThis, args); // use it here }, ms); }; diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md index 1516aca3..4f5867de 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md @@ -1,6 +1,4 @@ - - -```js run no-beautify +```js demo function debounce(f, ms) { let isCooldown = false; @@ -18,7 +16,7 @@ function debounce(f, ms) { } ``` -The call to `debounce` returns a wrapper. There may be two states: +A call to `debounce` returns a wrapper. There may be two states: - `isCooldown = false` -- ready to run. - `isCooldown = true` -- waiting for the timeout. diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md index 372ebedd..c844016d 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md @@ -1,4 +1,4 @@ -```js +```js demo function throttle(func, ms) { let isThrottled = false,