From 95249ec8a41c2c784e61a3d611382647d3e6a736 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:36:05 +0200 Subject: [PATCH 001/146] Create assembly-line --- config.json | 7 +++++++ .../concept/assembly-line/.docs/instructions.md | 0 .../concept/assembly-line/.docs/introduction.md | 0 exercises/concept/assembly-line/.meta/config.json | 15 +++++++++++++++ exercises/concept/assembly-line/.meta/exemplar.js | 0 exercises/concept/assembly-line/assembly-line.js | 0 .../concept/assembly-line/assembly-line.spec.js | 0 7 files changed, 22 insertions(+) create mode 100644 exercises/concept/assembly-line/.docs/instructions.md create mode 100644 exercises/concept/assembly-line/.docs/introduction.md create mode 100644 exercises/concept/assembly-line/.meta/config.json create mode 100644 exercises/concept/assembly-line/.meta/exemplar.js create mode 100644 exercises/concept/assembly-line/assembly-line.js create mode 100644 exercises/concept/assembly-line/assembly-line.spec.js diff --git a/config.json b/config.json index e36be78be3..b3b93cedb6 100644 --- a/config.json +++ b/config.json @@ -436,6 +436,13 @@ "objects", "functions" ] + }, + { + "slug": "assembly-line", + "name": "assembly-line", + "uuid": "16114449-52fe-470e-af11-cf9dc3689a93", + "concepts": [], + "prerequisites": [] } ], "practice": [ diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/assembly-line/.docs/introduction.md b/exercises/concept/assembly-line/.docs/introduction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json new file mode 100644 index 0000000000..11fadbc299 --- /dev/null +++ b/exercises/concept/assembly-line/.meta/config.json @@ -0,0 +1,15 @@ +{ + "authors": [], + "files": { + "solution": [ + "assembly-line.js" + ], + "test": [ + "assembly-line.spec.js" + ], + "exemplar": [ + ".meta/exemplar.js" + ] + }, + "blurb": "" +} diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js new file mode 100644 index 0000000000..e69de29bb2 From 22bd128a39fc626f1786946cfcbfe1008096a4cc Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:38:43 +0200 Subject: [PATCH 002/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index 11fadbc299..525d40ae62 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -1,5 +1,5 @@ { - "authors": [], + "authors": ["quintuple-mallard"], "files": { "solution": [ "assembly-line.js" @@ -11,5 +11,5 @@ ".meta/exemplar.js" ] }, - "blurb": "" + "blurb": "Learn about type checking while helping [company] manage their factory" } From 9704ea253602a3a63d2db6c7f4ca3cf5fb061598 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:43:17 +0200 Subject: [PATCH 003/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index 525d40ae62..735042e1b6 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -1,5 +1,7 @@ { "authors": ["quintuple-mallard"], + "prerequisites":["basics"], + "concepts":["type-checking"], "files": { "solution": [ "assembly-line.js" From 0b981f00aec6fbeabf2282c4b7def359b7470772 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:45:14 +0200 Subject: [PATCH 004/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index 735042e1b6..6d991b923f 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -1,7 +1,5 @@ { "authors": ["quintuple-mallard"], - "prerequisites":["basics"], - "concepts":["type-checking"], "files": { "solution": [ "assembly-line.js" @@ -11,7 +9,9 @@ ], "exemplar": [ ".meta/exemplar.js" - ] + ], + "prerequisites":["basics"], + "concepts":["type-checking"], }, "blurb": "Learn about type checking while helping [company] manage their factory" } From bbbb3cfdcc02817504ab38d9f58ffa3f0c27e841 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:46:42 +0200 Subject: [PATCH 005/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index 6d991b923f..fb9ff2592a 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -10,8 +10,6 @@ "exemplar": [ ".meta/exemplar.js" ], - "prerequisites":["basics"], - "concepts":["type-checking"], }, "blurb": "Learn about type checking while helping [company] manage their factory" } From 38950609eb2689f913d88aa8289e9811402fb092 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:47:33 +0200 Subject: [PATCH 006/146] Update config.json --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index b3b93cedb6..7319737fdc 100644 --- a/config.json +++ b/config.json @@ -441,8 +441,8 @@ "slug": "assembly-line", "name": "assembly-line", "uuid": "16114449-52fe-470e-af11-cf9dc3689a93", - "concepts": [], - "prerequisites": [] + "concepts":["type-checking"], + "prerequisites":["basics"] } ], "practice": [ From 5b4165f30548650533c3d139f9d798bdbd46f4a3 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:48:14 +0200 Subject: [PATCH 007/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index fb9ff2592a..525d40ae62 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -9,7 +9,7 @@ ], "exemplar": [ ".meta/exemplar.js" - ], + ] }, "blurb": "Learn about type checking while helping [company] manage their factory" } From a31d9d5c1307ecf740c517b8ac9357f149caeae0 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:50:51 +0200 Subject: [PATCH 008/146] Update config.json --- config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config.json b/config.json index 7319737fdc..537dcbea1c 100644 --- a/config.json +++ b/config.json @@ -2880,6 +2880,11 @@ "uuid": "ca322d6f-0f7e-4a2d-a058-e98a59cdae93", "slug": "randomness", "name": "Randomness" + }, + { + "uuid": "72e51fbe-db98-492e-b155-8ef21623f741", + "slug": "type-checking", + "name": "Type Checking" } ], "key_features": [ From 0c39de22db59942a5e1b78f71e3929f2c6e6386a Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:51:48 +0200 Subject: [PATCH 009/146] Create hints.md --- exercises/concept/assembly-line/.docs/hints.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/concept/assembly-line/.docs/hints.md diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/assembly-line/.docs/hints.md new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/exercises/concept/assembly-line/.docs/hints.md @@ -0,0 +1 @@ + From 15f1f7d9d6e00ef101b9f24f15cff41dabed365d Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:53:51 +0200 Subject: [PATCH 010/146] Create config.json --- concepts/type-checking/config.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 concepts/type-checking/config.json diff --git a/concepts/type-checking/config.json b/concepts/type-checking/config.json new file mode 100644 index 0000000000..d50db081eb --- /dev/null +++ b/concepts/type-checking/config.json @@ -0,0 +1,5 @@ +{ + "blurb": "Learn how to check the type of an object in JavaScript", + "authors": ["quintuple-mallard"], + "contributors": [] +} From e4628e315bda66522923386cc13dc653a2621f27 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 12:54:56 +0200 Subject: [PATCH 011/146] Rename concepts/type-checking/config.json to concepts/type-checking/.meta/config.json --- concepts/type-checking/{ => .meta}/config.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename concepts/type-checking/{ => .meta}/config.json (100%) diff --git a/concepts/type-checking/config.json b/concepts/type-checking/.meta/config.json similarity index 100% rename from concepts/type-checking/config.json rename to concepts/type-checking/.meta/config.json From fac410062f885519897f1d201ab0391b968376d4 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 13:12:21 +0200 Subject: [PATCH 012/146] Create about.md --- concepts/type-checking/about.md | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 concepts/type-checking/about.md diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md new file mode 100644 index 0000000000..af9fd7ac3c --- /dev/null +++ b/concepts/type-checking/about.md @@ -0,0 +1,34 @@ +# About + +Knowning what type an object has is often very important for code to run smoothly and without errors. + +Javascript has several ways to check the type of an object. + +## The `typeof` operator + +The `typeof` operator returns the type of its input. +The output is restricted to one of the [primitive data types][primitives], "function" or "object". +```javascript +typeof undefined +// => "undefined" + +typeof true +// => "boolean" + +typeof 42 +// => "number" + +typeof "Hello, World!" +// => "string" + +typeof [1,2,3,4] +// => "object" + +typeof typeof function () {return "Hello, World"} +// => "function" + +typeof {city: "Stockholm", country: "Sweden"} +// => "object" + +``` +[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive From 8b4cdd265b38bebe6b80854f619f16270bc2d64d Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 13:38:46 +0200 Subject: [PATCH 013/146] Update about.md --- concepts/type-checking/about.md | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index af9fd7ac3c..e57ee3a1e0 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -7,7 +7,7 @@ Javascript has several ways to check the type of an object. ## The `typeof` operator The `typeof` operator returns the type of its input. -The output is restricted to one of the [primitive data types][primitives], "function" or "object". +The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. ```javascript typeof undefined // => "undefined" @@ -21,14 +21,37 @@ typeof 42 typeof "Hello, World!" // => "string" +typeof function () {return "Hello, World"} +// => "function" + typeof [1,2,3,4] // => "object" -typeof typeof function () {return "Hello, World"} -// => "function" - typeof {city: "Stockholm", country: "Sweden"} // => "object" +``` +The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. + +## The `instanceof` operator + +For checking the type of an object, you can use the `instanceof` operator. +It returns a boolean depending on whether the second argument is included in the first arguments' [prototype chain][prototype chain]. +To clarify, `instanceof` will return whether the first argument is an instance of second argument or one of its child classes. + +```javascript +// The SpecialArray class is a child of the Array class. +class SpecialArray extends Array { + //... +} +const aSpecialArray = new SpecialArray + +aSpecialArray instanceof SpecialArray +// => true + +aSpecialArray instanceof Array +// => true ``` [primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive +[typeof null is object]: https://2ality.com/2013/10/typeof-null.html +[prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 646883347f091ce9f00445ad327f00b718edb336 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 13:39:34 +0200 Subject: [PATCH 014/146] Format 2 files --- config.json | 8 ++++++-- exercises/concept/assembly-line/.meta/config.json | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 537dcbea1c..ac24caf488 100644 --- a/config.json +++ b/config.json @@ -441,8 +441,12 @@ "slug": "assembly-line", "name": "assembly-line", "uuid": "16114449-52fe-470e-af11-cf9dc3689a93", - "concepts":["type-checking"], - "prerequisites":["basics"] + "concepts": [ + "type-checking" + ], + "prerequisites": [ + "basics" + ] } ], "practice": [ diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index 525d40ae62..ccc72550ec 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -1,5 +1,7 @@ { - "authors": ["quintuple-mallard"], + "authors": [ + "quintuple-mallard" + ], "files": { "solution": [ "assembly-line.js" From bae868a0593d411edfc8c1d393122e10d123b5bc Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 20:39:44 +0200 Subject: [PATCH 015/146] Update about.md --- concepts/type-checking/about.md | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index e57ee3a1e0..98f604c108 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -35,23 +35,37 @@ The one exception to this is that `typeof null` returns `"object"` for [historic ## The `instanceof` operator For checking the type of an object, you can use the `instanceof` operator. -It returns a boolean depending on whether the second argument is included in the first arguments' [prototype chain][prototype chain]. -To clarify, `instanceof` will return whether the first argument is an instance of second argument or one of its child classes. +It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. +`instanceof` only works for compound data types, such as arrays and objects. ```javascript -// The SpecialArray class is a child of the Array class. -class SpecialArray extends Array { - //... +class Beverage { + // ... } -const aSpecialArray = new SpecialArray +// The Dog class is a child of the Pet class. +class Coffee extends Beverage { + // ... +} +const java = new Coffee() -aSpecialArray instanceof SpecialArray +java instanceof Coffee // => true -aSpecialArray instanceof Array +java instanceof Beverage // => true ``` +~~~~exercism/advanced +The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. + +While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. + +This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +`Array.isArray()` is capable of ignoring this, and should always be used when possible. +~~~~ +## The `in` operator + [primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive [typeof null is object]: https://2ality.com/2013/10/typeof-null.html [prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 8f7d4e82c29aee1e50bf9d50d2bbd2dcd763b9cf Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 21:16:34 +0200 Subject: [PATCH 016/146] Update about.md --- concepts/type-checking/about.md | 62 ++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 98f604c108..8d68b3e8ac 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -43,7 +43,7 @@ To clarify, `instanceof` will return whether the first operand is an instance of class Beverage { // ... } -// The Dog class is a child of the Pet class. +// The Coffee class is a child of the Beverage class. class Coffee extends Beverage { // ... } @@ -66,6 +66,66 @@ This is because the Array class has a different constructor in each `iframe`, me ~~~~ ## The `in` operator +The `in` operator returns whether the first operand is a property of the second operand. +It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. +```javascript +class Coffee { + constructor() { + this.temperature = "hot"; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = "warm" + } +} +const espresso = new Coffee() + +"temperature" in espresso +// => true + +"color" in espresso +// => false + +"isDarkMatter" in espresso +// => true + +``` +~~~~exercism/note +`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +```javascript +"coolDown" in espresso +// => true + +"constructor" in espresso +// => true +``` +To avoid this, use the hasOwnProperty() method. +~~~~ +## The `hasOwnProperty()` method + +The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +```javascript +class Coffee{ + constructor() { + this.temperature = "hot"; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = "warm" + } +} +const cappuccino = new Coffee() + +cappuccino.hasOwnProperty("temperature") +// => true + +cappuccino.hasOwnProperty("constructor") +// => false + +cappuccino.hasOwnProperty("coolDown") +// => false +``` + [primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive [typeof null is object]: https://2ality.com/2013/10/typeof-null.html [prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 1cba79a6355d802e50358a03ebd8e476920ea786 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 26 Jun 2025 21:27:00 +0200 Subject: [PATCH 017/146] Format --- concepts/type-checking/about.md | 68 +++++++++++-------- .../concept/assembly-line/.docs/hints.md | 1 - 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 8d68b3e8ac..c80f2bb781 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -6,30 +6,34 @@ Javascript has several ways to check the type of an object. ## The `typeof` operator -The `typeof` operator returns the type of its input. +The `typeof` operator returns the type of its input. The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. + ```javascript -typeof undefined +typeof undefined; // => "undefined" -typeof true +typeof true; // => "boolean" -typeof 42 +typeof 42; // => "number" -typeof "Hello, World!" +typeof 'Hello, World!'; // => "string" -typeof function () {return "Hello, World"} +typeof function () { + return 'Hello, World'; +}; // => "function" -typeof [1,2,3,4] +typeof [1, 2, 3, 4]; // => "object" -typeof {city: "Stockholm", country: "Sweden"} +typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" ``` + The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. ## The `instanceof` operator @@ -47,50 +51,52 @@ class Beverage { class Coffee extends Beverage { // ... } -const java = new Coffee() +const java = new Coffee(); -java instanceof Coffee +java instanceof Coffee; // => true -java instanceof Beverage +java instanceof Beverage; // => true - ``` -~~~~exercism/advanced + +```exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. -~~~~ +``` + ## The `in` operator The `in` operator returns whether the first operand is a property of the second operand. It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. + ```javascript class Coffee { constructor() { - this.temperature = "hot"; + this.temperature = 'hot'; this.isDarkMatter = undefined; } coolDown() { - this.temperature = "warm" + this.temperature = 'warm'; } } -const espresso = new Coffee() +const espresso = new Coffee(); -"temperature" in espresso +'temperature' in espresso; // => true -"color" in espresso +'color' in espresso; // => false -"isDarkMatter" in espresso +'isDarkMatter' in espresso; // => true - ``` -~~~~exercism/note + +````exercism/note `in` can be slightly unreliable, as it will return `true` for inherited properties and methods. ```javascript "coolDown" in espresso @@ -100,29 +106,31 @@ const espresso = new Coffee() // => true ``` To avoid this, use the hasOwnProperty() method. -~~~~ +```` + ## The `hasOwnProperty()` method The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. + ```javascript -class Coffee{ +class Coffee { constructor() { - this.temperature = "hot"; + this.temperature = 'hot'; this.isDarkMatter = undefined; } coolDown() { - this.temperature = "warm" + this.temperature = 'warm'; } } -const cappuccino = new Coffee() +const cappuccino = new Coffee(); -cappuccino.hasOwnProperty("temperature") +cappuccino.hasOwnProperty('temperature'); // => true -cappuccino.hasOwnProperty("constructor") +cappuccino.hasOwnProperty('constructor'); // => false -cappuccino.hasOwnProperty("coolDown") +cappuccino.hasOwnProperty('coolDown'); // => false ``` diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/assembly-line/.docs/hints.md index 8b13789179..e69de29bb2 100644 --- a/exercises/concept/assembly-line/.docs/hints.md +++ b/exercises/concept/assembly-line/.docs/hints.md @@ -1 +0,0 @@ - From 1bc0bcff4189ce4386f1d2248da0a14382c82a9f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 10:11:27 +0200 Subject: [PATCH 018/146] Create introduction.md --- concepts/type-checking/introduction.md | 139 +++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 concepts/type-checking/introduction.md diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md new file mode 100644 index 0000000000..c80f2bb781 --- /dev/null +++ b/concepts/type-checking/introduction.md @@ -0,0 +1,139 @@ +# About + +Knowning what type an object has is often very important for code to run smoothly and without errors. + +Javascript has several ways to check the type of an object. + +## The `typeof` operator + +The `typeof` operator returns the type of its input. +The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. + +```javascript +typeof undefined; +// => "undefined" + +typeof true; +// => "boolean" + +typeof 42; +// => "number" + +typeof 'Hello, World!'; +// => "string" + +typeof function () { + return 'Hello, World'; +}; +// => "function" + +typeof [1, 2, 3, 4]; +// => "object" + +typeof { city: 'Stockholm', country: 'Sweden' }; +// => "object" +``` + +The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. + +## The `instanceof` operator + +For checking the type of an object, you can use the `instanceof` operator. +It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. +`instanceof` only works for compound data types, such as arrays and objects. + +```javascript +class Beverage { + // ... +} +// The Coffee class is a child of the Beverage class. +class Coffee extends Beverage { + // ... +} +const java = new Coffee(); + +java instanceof Coffee; +// => true + +java instanceof Beverage; +// => true +``` + +```exercism/advanced +The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. + +While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. + +This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +`Array.isArray()` is capable of ignoring this, and should always be used when possible. +``` + +## The `in` operator + +The `in` operator returns whether the first operand is a property of the second operand. +It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = 'warm'; + } +} +const espresso = new Coffee(); + +'temperature' in espresso; +// => true + +'color' in espresso; +// => false + +'isDarkMatter' in espresso; +// => true +``` + +````exercism/note +`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +```javascript +"coolDown" in espresso +// => true + +"constructor" in espresso +// => true +``` +To avoid this, use the hasOwnProperty() method. +```` + +## The `hasOwnProperty()` method + +The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = 'warm'; + } +} +const cappuccino = new Coffee(); + +cappuccino.hasOwnProperty('temperature'); +// => true + +cappuccino.hasOwnProperty('constructor'); +// => false + +cappuccino.hasOwnProperty('coolDown'); +// => false +``` + +[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive +[typeof null is object]: https://2ality.com/2013/10/typeof-null.html +[prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 3ade67604fa7b71783bf2c05e732f3088eda120f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 10:18:26 +0200 Subject: [PATCH 019/146] Create links.json --- concepts/type-checking/links.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 concepts/type-checking/links.json diff --git a/concepts/type-checking/links.json b/concepts/type-checking/links.json new file mode 100644 index 0000000000..a8e4a31740 --- /dev/null +++ b/concepts/type-checking/links.json @@ -0,0 +1,14 @@ +[ + { + "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof", + "description": "MDN: The typeof operator" + }, + { + "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof", + "description": "MDN: The instanceof operator" + }, + { + "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty", + "description": "MDN: The object.hasOwnProperty() method" + } +] From 5086219e98eab32e5ff07ec3f74824fd38cb2ff4 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 10:34:00 +0200 Subject: [PATCH 020/146] Update config.json --- exercises/concept/assembly-line/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/assembly-line/.meta/config.json index ccc72550ec..7f4a1f696f 100644 --- a/exercises/concept/assembly-line/.meta/config.json +++ b/exercises/concept/assembly-line/.meta/config.json @@ -13,5 +13,5 @@ ".meta/exemplar.js" ] }, - "blurb": "Learn about type checking while helping [company] manage their factory" + "blurb": "Learn about type checking while helping manage an assembly line" } From 5af6d696fb33cbea8af80fed93d37d59b7f00f80 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 10:35:09 +0200 Subject: [PATCH 021/146] Update introduction.md --- .../assembly-line/.docs/introduction.md | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/introduction.md b/exercises/concept/assembly-line/.docs/introduction.md index e69de29bb2..99235c62a2 100644 --- a/exercises/concept/assembly-line/.docs/introduction.md +++ b/exercises/concept/assembly-line/.docs/introduction.md @@ -0,0 +1,139 @@ +# About + +Knowning what type an object has is often very important for code to run smoothly and without errors. + +Javascript has several ways to check the type of an object. + +## The `typeof` operator + +The `typeof` operator returns the type of its input. +The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. + +```javascript +typeof undefined; +// => "undefined" + +typeof true; +// => "boolean" + +typeof 42; +// => "number" + +typeof 'Hello, World!'; +// => "string" + +typeof function () { + return 'Hello, World'; +}; +// => "function" + +typeof [1, 2, 3, 4]; +// => "object" + +typeof { city: 'Stockholm', country: 'Sweden' }; +// => "object" +``` + +The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. + +## The `instanceof` operator + +For checking the type of an object, you can use the `instanceof` operator. +It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. +`instanceof` only works for compound data types, such as arrays and objects. + +```javascript +class Beverage { + // ... +} +// The Coffee class is a child of the Beverage class. +class Coffee extends Beverage { + // ... +} +const java = new Coffee(); + +java instanceof Coffee; +// => true + +java instanceof Beverage; +// => true +``` + +```exercism/advanced +The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. + +While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. + +This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +`Array.isArray()` is capable of ignoring this, and should always be used when possible. +``` + +## The `in` operator + +The `in` operator returns whether the first operand is a property of the second operand. +It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = 'warm'; + } +} +const espresso = new Coffee(); + +'temperature' in espresso; +// => true + +'color' in espresso; +// => false + +'isDarkMatter' in espresso; +// => true +``` + +````exercism/note +`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +```javascript +"coolDown" in espresso +// => true + +"constructor" in espresso +// => true +``` +To avoid this, use the hasOwnProperty() method. +```` + +## The `hasOwnProperty()` method + +The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = 'warm'; + } +} +const cappuccino = new Coffee(); + +cappuccino.hasOwnProperty('temperature'); +// => true + +cappuccino.hasOwnProperty('constructor'); +// => false + +cappuccino.hasOwnProperty('coolDown'); +// => false +``` + +[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive +[typeof null is object]: https://2ality.com/2013/10/typeof-null.html +[prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 8f74707aa0af2c401651ed77fd6ab250318978a6 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 11:26:04 +0200 Subject: [PATCH 022/146] Update instructions.md Still not done! --- .../assembly-line/.docs/instructions.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index e69de29bb2..904c062d17 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -0,0 +1,87 @@ +## Instructions + +### 1. Check if a value is a boolean + +Implement the `isBoolean` function, that checks if a value is a boolean. + +### 2. Check if a value is a number. + +Implement the `isNumber` function, that checks if a value is a _finite_ number or bigint, ie not `NaN` or `Infinity`. + +```javascript +isNumber(42) +// => true + +isNumber("Hello, World!") +// => false + +isNumber(NaN) +// => false +``` + +### 3. Check if a value is an object + +Implement the `isObject` function, that should check if the value is actually an object (so not null) + +```javascript +isObject({greeting:"Hello"}) +// => true + +isObject(25n) +// => false +``` + +### 4. Check if a string is numeric + +Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. + +```javascript +isNumericString("42") +// => true + +isNumericString("Hi!") +// => false +``` + +### 5. Check if an object is electronic + +Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. + +```javascript +class Duck { + //... +} +class WashingMachine extends ElectronicDevice { + //... +} +isElectronic(new Duck()) +// => false + +isElectronic(new WashingMachine()) +// => false +``` + +### 6. Check if a value is an empty array + +Implement the `isEmptyArray` function, that checks if an object is an empty array. +```javascript +isEmptyArray([1,2,3]) +// => false + +isEmptyArray([]) +// => true +``` + +### 7. Throw an error if an object does not have the `id` property + +Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. + +If an object does have the `id` property, it should return `undefined`. + +```javascript +assertHasId({id:42,color:"red"}) +// => undefined + +assertHasId({color:"green"}) +// Error: "Object is missing the 'id' property" +``` From 22c9e2525d2559b515f385d2eb0b61792b98f383 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 14:02:09 +0200 Subject: [PATCH 023/146] Update instructions.md --- .../assembly-line/.docs/instructions.md | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index 904c062d17..4c909fa90b 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -3,6 +3,13 @@ ### 1. Check if a value is a boolean Implement the `isBoolean` function, that checks if a value is a boolean. +```javascript +isBoolean(true) +// => true + +isBoolean(null) +// => false +``` ### 2. Check if a value is a number. @@ -21,7 +28,7 @@ isNumber(NaN) ### 3. Check if a value is an object -Implement the `isObject` function, that should check if the value is actually an object (so not null) +Implement the `isObject` function, that should check if the value is actually an object, not null. ```javascript isObject({greeting:"Hello"}) @@ -36,11 +43,15 @@ isObject(25n) Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. ```javascript +isNumericString(42) +// => false + isNumericString("42") // => true isNumericString("Hi!") // => false + ``` ### 5. Check if an object is electronic @@ -72,7 +83,18 @@ isEmptyArray([]) // => true ``` -### 7. Throw an error if an object does not have the `id` property +### 7. Check if a value is a non empty array + +Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. +```javascript +isNonEmptyArray([1,2,3]) +// => true + +isNonEmptyArray([]) +// => false +``` + +### 8. Throw an error if an object does not have the `id` property Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. @@ -85,3 +107,5 @@ assertHasId({id:42,color:"red"}) assertHasId({color:"green"}) // Error: "Object is missing the 'id' property" ``` + +### 9. From 728020debf77df1d7a7618d92a5e10b2bb829a67 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 14:03:15 +0200 Subject: [PATCH 024/146] Node.js magic --- exercises/concept/assembly-line/.gitignore | 5 +++ exercises/concept/assembly-line/.npmrc | 1 + exercises/concept/assembly-line/LICENSE | 21 +++++++++ .../concept/assembly-line/babel.config.js | 4 ++ .../concept/assembly-line/eslint.config.mjs | 45 +++++++++++++++++++ .../concept/assembly-line/jest.config.js | 22 +++++++++ exercises/concept/assembly-line/package.json | 38 ++++++++++++++++ 7 files changed, 136 insertions(+) create mode 100644 exercises/concept/assembly-line/.gitignore create mode 100644 exercises/concept/assembly-line/.npmrc create mode 100644 exercises/concept/assembly-line/LICENSE create mode 100644 exercises/concept/assembly-line/babel.config.js create mode 100644 exercises/concept/assembly-line/eslint.config.mjs create mode 100644 exercises/concept/assembly-line/jest.config.js create mode 100644 exercises/concept/assembly-line/package.json diff --git a/exercises/concept/assembly-line/.gitignore b/exercises/concept/assembly-line/.gitignore new file mode 100644 index 0000000000..0c88ff6ec3 --- /dev/null +++ b/exercises/concept/assembly-line/.gitignore @@ -0,0 +1,5 @@ +/node_modules +/bin/configlet +/bin/configlet.exe +/package-lock.json +/yarn.lock diff --git a/exercises/concept/assembly-line/.npmrc b/exercises/concept/assembly-line/.npmrc new file mode 100644 index 0000000000..d26df800bb --- /dev/null +++ b/exercises/concept/assembly-line/.npmrc @@ -0,0 +1 @@ +audit=false diff --git a/exercises/concept/assembly-line/LICENSE b/exercises/concept/assembly-line/LICENSE new file mode 100644 index 0000000000..90e73be03b --- /dev/null +++ b/exercises/concept/assembly-line/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Exercism + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/exercises/concept/assembly-line/babel.config.js b/exercises/concept/assembly-line/babel.config.js new file mode 100644 index 0000000000..a638497df1 --- /dev/null +++ b/exercises/concept/assembly-line/babel.config.js @@ -0,0 +1,4 @@ +module.exports = { + presets: [['@exercism/babel-preset-javascript', { corejs: '3.40' }]], + plugins: [], +}; diff --git a/exercises/concept/assembly-line/eslint.config.mjs b/exercises/concept/assembly-line/eslint.config.mjs new file mode 100644 index 0000000000..ca517111ed --- /dev/null +++ b/exercises/concept/assembly-line/eslint.config.mjs @@ -0,0 +1,45 @@ +// @ts-check + +import config from '@exercism/eslint-config-javascript'; +import maintainersConfig from '@exercism/eslint-config-javascript/maintainers.mjs'; + +import globals from 'globals'; + +export default [ + ...config, + ...maintainersConfig, + { + files: maintainersConfig[1].files, + rules: { + 'jest/expect-expect': ['warn', { assertFunctionNames: ['expect*'] }], + }, + }, + { + files: ['scripts/**/*.mjs'], + languageOptions: { + globals: { + ...globals.node, + }, + }, + }, + // <> + { + ignores: [ + // # Protected or generated + '/.appends/**/*', + '/.github/**/*', + '/.vscode/**/*', + + // # Binaries + '/bin/*', + + // # Configuration + '/config', + '/babel.config.js', + + // # Typings + '/exercises/**/global.d.ts', + '/exercises/**/env.d.ts', + ], + }, +]; diff --git a/exercises/concept/assembly-line/jest.config.js b/exercises/concept/assembly-line/jest.config.js new file mode 100644 index 0000000000..ec8e908127 --- /dev/null +++ b/exercises/concept/assembly-line/jest.config.js @@ -0,0 +1,22 @@ +module.exports = { + verbose: true, + projects: [''], + testMatch: [ + '**/__tests__/**/*.[jt]s?(x)', + '**/test/**/*.[jt]s?(x)', + '**/?(*.)+(spec|test).[jt]s?(x)', + ], + testPathIgnorePatterns: [ + '/(?:production_)?node_modules/', + '.d.ts$', + '/test/fixtures', + '/test/helpers', + '__mocks__', + ], + transform: { + '^.+\\.[jt]sx?$': 'babel-jest', + }, + moduleNameMapper: { + '^(\\.\\/.+)\\.js$': '$1', + }, +}; diff --git a/exercises/concept/assembly-line/package.json b/exercises/concept/assembly-line/package.json new file mode 100644 index 0000000000..c25a17f074 --- /dev/null +++ b/exercises/concept/assembly-line/package.json @@ -0,0 +1,38 @@ +{ + "name": "@exercism/javascript-concept-assembly-line", + "description": "Exercism concept exercise on assembly-line", + "author": "Katrina Owen", + "contributors": [ + "Derk-Jan Karrenbeld (https://derk-jan.com)", + "Tejas Bubane (https://tejasbubane.github.io/)" + ], + "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/exercism/javascript", + "directory": "exercises/concept/assembly-line" + }, + "devDependencies": { + "@exercism/babel-preset-javascript": "^0.5.1", + "@exercism/eslint-config-javascript": "^0.8.1", + "@jest/globals": "^29.7.0", + "@types/node": "^22.15.29", + "@types/shelljs": "^0.8.16", + "babel-jest": "^29.7.0", + "core-js": "~3.42.0", + "diff": "^8.0.2", + "eslint": "^9.28.0", + "expect": "^29.7.0", + "globals": "^16.2.0", + "jest": "^29.7.0" + }, + "dependencies": {}, + "scripts": { + "lint": "corepack pnpm eslint .", + "test": "corepack pnpm jest", + "watch": "corepack pnpm jest --watch", + "format": "corepack pnpm prettier -w ." + }, + "packageManager": "pnpm@9.15.2" +} From 5a7d15316c0765b5906f68305cf7e27c1403ff7c Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 14:35:48 +0200 Subject: [PATCH 025/146] Update package.json --- exercises/concept/assembly-line/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/package.json b/exercises/concept/assembly-line/package.json index c25a17f074..91bb1a394d 100644 --- a/exercises/concept/assembly-line/package.json +++ b/exercises/concept/assembly-line/package.json @@ -1,6 +1,6 @@ { "name": "@exercism/javascript-concept-assembly-line", - "description": "Exercism concept exercise on assembly-line", + "description": "Exercism concept exercise on type checking", "author": "Katrina Owen", "contributors": [ "Derk-Jan Karrenbeld (https://derk-jan.com)", From d9a7f8b27b2dce7cebf012127531eb30cbeca855 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 14:47:05 +0200 Subject: [PATCH 026/146] Update instructions.md --- .../assembly-line/.docs/instructions.md | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index 4c909fa90b..e4d717c027 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -75,6 +75,7 @@ isElectronic(new WashingMachine()) ### 6. Check if a value is an empty array Implement the `isEmptyArray` function, that checks if an object is an empty array. + ```javascript isEmptyArray([1,2,3]) // => false @@ -98,7 +99,7 @@ isNonEmptyArray([]) Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. -If an object does have the `id` property, it should return `undefined`. +If an object does have the `id` property, it should not return anything. ```javascript assertHasId({id:42,color:"red"}) @@ -108,4 +109,34 @@ assertHasId({color:"green"}) // Error: "Object is missing the 'id' property" ``` -### 9. +### 9. Check if an object has the `type` property + +Implement the `hasType` function, that checks whether an object has a `type` property. + +```javascript +hasType({type:"car",color:"red"}) +// => true + +hasType({color:"green"}) +// => false +``` + +### 10. Check if an object has a non inherited `type` property + +Implement the `hasNonInheritedType` function, that checks whether an object has a `type` property that has not been inherited. +# Fix this! +```javascript +class Heater { + constructor() { + this.type = "heater" + } +} +class Radiator { + +} +hasNonInheritedType() +// => true + +hasNonInheritedType() +// => false +``` From a1c7fc0fb636f28869e87bfdeb5c42fd8d265800 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 18:04:08 +0200 Subject: [PATCH 027/146] Update instructions.md --- .../assembly-line/.docs/instructions.md | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index e4d717c027..33187c7785 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -1,8 +1,13 @@ ## Instructions +You have been hired by a company that makes various products. +Due to lack of space, all the products are made on the same assembly line, but this has lead to products exiting the factory as unusable piles of metal, glass, and wood. +To fix this, you have been tasked with making functions to identify the type of a product. + ### 1. Check if a value is a boolean Implement the `isBoolean` function, that checks if a value is a boolean. + ```javascript isBoolean(true) // => true @@ -15,6 +20,9 @@ isBoolean(null) Implement the `isNumber` function, that checks if a value is a _finite_ number or bigint, ie not `NaN` or `Infinity`. +Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. +Your function should be able to correctly handle this as well. + ```javascript isNumber(42) // => true @@ -22,6 +30,9 @@ isNumber(42) isNumber("Hello, World!") // => false +isNumber(42n) +// => true + isNumber(NaN) // => false ``` @@ -72,27 +83,27 @@ isElectronic(new WashingMachine()) // => false ``` -### 6. Check if a value is an empty array +### 6. Check if a value is a non empty array -Implement the `isEmptyArray` function, that checks if an object is an empty array. +Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. ```javascript -isEmptyArray([1,2,3]) -// => false - -isEmptyArray([]) +isNonEmptyArray([1,2,3]) // => true + +isNonEmptyArray([]) +// => false ``` -### 7. Check if a value is a non empty array +### 7. Check if a value is an empty array -Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. +Implement the `isEmptyArray` function, that checks if an object is an empty array. ```javascript -isNonEmptyArray([1,2,3]) -// => true - -isNonEmptyArray([]) +isEmptyArray([1,2,3]) // => false + +isEmptyArray([]) +// => true ``` ### 8. Throw an error if an object does not have the `id` property @@ -109,7 +120,7 @@ assertHasId({color:"green"}) // Error: "Object is missing the 'id' property" ``` -### 9. Check if an object has the `type` property +### 9. Check if an object has a `type` property Implement the `hasType` function, that checks whether an object has a `type` property. @@ -121,22 +132,28 @@ hasType({color:"green"}) // => false ``` -### 10. Check if an object has a non inherited `type` property +### 10. Check if an object has a `constructor` property + +Implement the `hasConstructorProperty` function, that checks whether an object has a `constructor` property. -Implement the `hasNonInheritedType` function, that checks whether an object has a `type` property that has not been inherited. -# Fix this! ```javascript -class Heater { +class MyClass { constructor() { - this.type = "heater" + this.number = "42" } } -class Radiator { - +class MyNewClass extends MyClass { + constructor() { + this.number = "42" + this.constructor = "A constructor" + } } -hasNonInheritedType() -// => true +hasConstructorProperty(MyClass) +// => false -hasNonInheritedType() +hasConstructorProperty(MySecondClass) // => false ``` +### 11. Check if an object has a defined `type` property + +Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. From 595ecba0ae6a555501261627cb7f39eb54132a0f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 18:31:55 +0200 Subject: [PATCH 028/146] Update instructions.md --- exercises/concept/assembly-line/.docs/instructions.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index 33187c7785..2e34a9427a 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -157,3 +157,11 @@ hasConstructorProperty(MySecondClass) ### 11. Check if an object has a defined `type` property Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. + +```javascript +hasDefinedType({type:undefined,color:"red"}) +// => false + +hasDefinedType({type:"car",color:"green"}) +// => true +``` From 90b0cd3030947266e173f3200d77832cc6c1b980 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 18:41:33 +0200 Subject: [PATCH 029/146] Update assembly-line.js Create all the functions using typeof --- .../concept/assembly-line/assembly-line.js | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index e69de29bb2..dc7e5c7b79 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -0,0 +1,55 @@ +// @ts-check +// +// The line above enables type checking for this file. Various IDEs interpret +// the @ts-check directive. It will give you helpful autocompletion when +// implementing this exercise. + +/** + * Checks if input is a boolean. + * + * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @returns {boolean} whether the input is a boolean + */ +export function isBoolean(value) { + throw new Error("Remove this line and implement the isBoolean function") +} + +/** + * Checks if input is a finite number or bigint. + * + * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @returns {boolean} whether the input is a finite number or bigint + */ +export function isNumber(value) { + throw new Error("Remove this line and implement the isNumber function") +} + +/** + * Checks if a value is an object. + * + * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @returns {boolean} whether the input is an object. + */ +export function isObject(value) { + throw new Error("Remove this line and implement the isObject function") +} + +/** + * Checks if a value is a numeric string. + * + * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @returns {boolean} whether the input is a numeric string. + */ +export function isNumericString(value) { + throw new Error("Remove this line and implement the isNumericString function") +} + +/** + * Checks if a value is an object. + * + * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @returns {boolean} whether the input is an object. + */ +export function isElectronic(value) { + throw new Error("Remove this line and implement the isElectronic function") +} From 55e7611f5d3377fe51639f7a4c16eb0b438830c8 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 19:32:29 +0200 Subject: [PATCH 030/146] Update assembly-line.js --- exercises/concept/assembly-line/assembly-line.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index dc7e5c7b79..58e0618ca2 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -4,6 +4,9 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. +class ElectronicDevice { + // This is a class for use in the exercise. +} /** * Checks if input is a boolean. * @@ -45,11 +48,11 @@ export function isNumericString(value) { } /** - * Checks if a value is an object. + * Checks if a value is an instance of the `ElectronicDevice` class or one of its children. * - * @param {number|boolean|string|null|undefined|symbol|bigint|object} value - * @returns {boolean} whether the input is an object. + * @param {object} object + * @returns {boolean} whether the input is an instance of the `ElectronicDevice` class or one of its children. */ -export function isElectronic(value) { +export function isElectronic(object) { throw new Error("Remove this line and implement the isElectronic function") } From a27ef2ba670bc854b5bb55531e64ffa7bd961aa4 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 19:51:42 +0200 Subject: [PATCH 031/146] Update assembly-line.js --- .../concept/assembly-line/assembly-line.js | 56 ++++++++++++++++--- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index 58e0618ca2..a93fb0a936 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -5,12 +5,12 @@ // implementing this exercise. class ElectronicDevice { - // This is a class for use in the exercise. -} + // This class will be used in the exercise. +} /** * Checks if input is a boolean. * - * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @param {any} value * @returns {boolean} whether the input is a boolean */ export function isBoolean(value) { @@ -20,7 +20,7 @@ export function isBoolean(value) { /** * Checks if input is a finite number or bigint. * - * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @param {any} value * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { @@ -30,7 +30,7 @@ export function isNumber(value) { /** * Checks if a value is an object. * - * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @param {any} value * @returns {boolean} whether the input is an object. */ export function isObject(value) { @@ -40,7 +40,7 @@ export function isObject(value) { /** * Checks if a value is a numeric string. * - * @param {number|boolean|string|null|undefined|symbol|bigint|object} value + * @param {any} value * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { @@ -48,11 +48,51 @@ export function isNumericString(value) { } /** - * Checks if a value is an instance of the `ElectronicDevice` class or one of its children. + * Checks if an object is an instance of the `ElectronicDevice` class or one of its children. * * @param {object} object - * @returns {boolean} whether the input is an instance of the `ElectronicDevice` class or one of its children. + * @returns {boolean} whether the object is an instance of the `ElectronicDevice` class or one of its children. */ export function isElectronic(object) { throw new Error("Remove this line and implement the isElectronic function") } + +/** + * Checks if a value is a non empty array. + * + * @param {any} value + * @returns {boolean} whether the input is a non empty array. + */ +export function isNonEmptyArray(value) { + throw new Error("Remove this line and implement the isNonEmptyArray function") +} + +/** + * Checks if a value is an empty array. + * + * @param {any} value + * @returns {boolean} whether the input is an empty array. + */ +export function isEmptyArray(value) { + throw new Error("Remove this line and implement the isEmptyArray function") +} + +/** + * Checks if a value is an empty array. + * + * @param {object} object + * @returns {undefined|error} undefined if the input has an `id` property, otherwise throws an error. + */ +export function assertHasId(object) { + throw new Error("Remove this line and implement the assertHasId function") +} + +/** + * Checks if a value is an empty array. + * + * @param {object} object + * @returns {undefined|error} whether the input has a `type` property. + */ +export function hasType(object) { + throw new Error("Remove this line and implement the hasType function") +} From aced68aefe72b1b884b55006397721f33e71465a Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 19:55:33 +0200 Subject: [PATCH 032/146] Update instructions.md --- exercises/concept/assembly-line/.docs/instructions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index 2e34a9427a..be45da5328 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -142,7 +142,7 @@ class MyClass { this.number = "42" } } -class MyNewClass extends MyClass { +class MyNewClass { constructor() { this.number = "42" this.constructor = "A constructor" @@ -151,8 +151,8 @@ class MyNewClass extends MyClass { hasConstructorProperty(MyClass) // => false -hasConstructorProperty(MySecondClass) -// => false +hasConstructorProperty(MyNewClass) +// => true ``` ### 11. Check if an object has a defined `type` property From e38bb7a38201dec93344869d85dc7510f34ea166 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 20:02:50 +0200 Subject: [PATCH 033/146] Update assembly-line.js --- .../concept/assembly-line/assembly-line.js | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index a93fb0a936..eb3edc71fe 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -78,21 +78,41 @@ export function isEmptyArray(value) { } /** - * Checks if a value is an empty array. + * Throws an error if an object is missing an "id" property. * * @param {object} object - * @returns {undefined|error} undefined if the input has an `id` property, otherwise throws an error. + * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. */ export function assertHasId(object) { throw new Error("Remove this line and implement the assertHasId function") } /** - * Checks if a value is an empty array. + * Checks if a value has a "type" property. * * @param {object} object - * @returns {undefined|error} whether the input has a `type` property. + * @returns {boolean} whether the input has a "type" property. */ export function hasType(object) { throw new Error("Remove this line and implement the hasType function") } + +/** + * Checks if a value has a "constructor" property. + * + * @param {object} object + * @returns {boolean} whether the input has a "constructor" property. + */ +export function hasConstructorProperty(object) { + throw new Error("Remove this line and implement the hasConstructorProperty function") +} + +/** + * Checks if a value has a defined "type" property. + * + * @param {object} object + * @returns {boolean} whether the input has a defined "type" property. + */ +export function hasDefinedType(object) { + throw new Error("Remove this line and implement the hasDefinedType function") +} From 24bad9da9e6b6bd7df71fd850dd1f55a2f0b4835 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 27 Jun 2025 20:09:16 +0200 Subject: [PATCH 034/146] Update exemplar.js --- .../concept/assembly-line/.meta/exemplar.js | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index e69de29bb2..0eff9986ef 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -0,0 +1,121 @@ +// @ts-check +// +// The line above enables type checking for this file. Various IDEs interpret +// the @ts-check directive. It will give you helpful autocompletion when +// implementing this exercise. + +class ElectronicDevice { + // This class will be used in the exercise. +} +/** + * Checks if input is a boolean. + * + * @param {any} value + * @returns {boolean} whether the input is a boolean + */ +export function isBoolean(value) { + return typeof value === "boolean" +} + +/** + * Checks if input is a finite number or bigint. + * + * @param {any} value + * @returns {boolean} whether the input is a finite number or bigint + */ +export function isNumber(value) { + return (typeof value === "number"||typeof value === "bigint") && !isNan(value) +} + +/** + * Checks if a value is an object. + * + * @param {any} value + * @returns {boolean} whether the input is an object. + */ +export function isObject(value) { + return value !== null && typeof value === "object" +} + +/** + * Checks if a value is a numeric string. + * + * @param {any} value + * @returns {boolean} whether the input is a numeric string. + */ +export function isNumericString(value) { + return isNumber(Number(value)) +} + +/** + * Checks if an object is an instance of the "ElectronicDevice" class or one of its children. + * + * @param {object} object + * @returns {boolean} whether the object is an instance of the "ElectronicDevice" class or one of its children. + */ +export function isElectronic(object) { + return object instanceof ElectronicDevice +} + +/** + * Checks if a value is a non empty array. + * + * @param {any} value + * @returns {boolean} whether the input is a non empty array. + */ +export function isNonEmptyArray(value) { + return value instanceof Array && value !== [] +} + +/** + * Checks if a value is an empty array. + * + * @param {any} value + * @returns {boolean} whether the input is an empty array. + */ +export function isEmptyArray(value) { + return value === [] +} + +/** + * Throws an error if an object is missing an "id" property. + * + * @param {object} object + * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. + */ +export function assertHasId(object) { + if ("id" in object){ + return; + } + throw new Error('The "id" property is missing.') +} + +/** + * Checks if a value has a "type" property. + * + * @param {object} object + * @returns {boolean} whether the input has a "type" property. + */ +export function hasType(object) { + throw new Error("Remove this line and implement the hasType function") +} + +/** + * Checks if a value has a "constructor" property. + * + * @param {object} object + * @returns {boolean} whether the input has a "constructor" property. + */ +export function hasConstructorProperty(object) { + throw new Error("Remove this line and implement the hasConstructorProperty function") +} + +/** + * Checks if a value has a defined "type" property. + * + * @param {object} object + * @returns {boolean} whether the input has a defined "type" property. + */ +export function hasDefinedType(object) { + throw new Error("Remove this line and implement the hasDefinedType function") +} From 8ccb0c5078e32715be41ba8aef84958da45d7113 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 10:59:48 +0200 Subject: [PATCH 035/146] Update exemplar.js fix isnan() --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 0eff9986ef..9f53e9666b 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -24,7 +24,7 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNan(value) + return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) } /** From 57b21c921b6c5893d535ea344ef04f33cb235640 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:25:20 +0200 Subject: [PATCH 036/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 9f53e9666b..f0de65dd39 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -64,7 +64,7 @@ export function isElectronic(object) { * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { - return value instanceof Array && value !== [] + return value instanceof Array && value.length < 0 } /** @@ -74,7 +74,7 @@ export function isNonEmptyArray(value) { * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { - return value === [] + return value instanceof Array && value.length === 0 } /** @@ -97,7 +97,7 @@ export function assertHasId(object) { * @returns {boolean} whether the input has a "type" property. */ export function hasType(object) { - throw new Error("Remove this line and implement the hasType function") + return "type" in object } /** @@ -107,7 +107,7 @@ export function hasType(object) { * @returns {boolean} whether the input has a "constructor" property. */ export function hasConstructorProperty(object) { - throw new Error("Remove this line and implement the hasConstructorProperty function") + return object.hasOwnProperty("constructor") } /** From f0c9186700190667595b4241431090e5d30bb3a5 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:29:49 +0200 Subject: [PATCH 037/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index f0de65dd39..3966968758 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -107,7 +107,7 @@ export function hasType(object) { * @returns {boolean} whether the input has a "constructor" property. */ export function hasConstructorProperty(object) { - return object.hasOwnProperty("constructor") + return Object.hasOwn(object,"constructor") } /** @@ -117,5 +117,5 @@ export function hasConstructorProperty(object) { * @returns {boolean} whether the input has a defined "type" property. */ export function hasDefinedType(object) { - throw new Error("Remove this line and implement the hasDefinedType function") + return hasType(object) && object.type !== undefined } From 8020cfa786be2bee7d65faf03bb5d710c464eedc Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:32:12 +0200 Subject: [PATCH 038/146] Update introduction.md --- exercises/concept/assembly-line/.docs/introduction.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/introduction.md b/exercises/concept/assembly-line/.docs/introduction.md index 99235c62a2..5251310995 100644 --- a/exercises/concept/assembly-line/.docs/introduction.md +++ b/exercises/concept/assembly-line/.docs/introduction.md @@ -108,15 +108,14 @@ const espresso = new Coffee(); To avoid this, use the hasOwnProperty() method. ```` -## The `hasOwnProperty()` method +## The `Object.hasOwn()` function -The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. ```javascript class Coffee { constructor() { this.temperature = 'hot'; - this.isDarkMatter = undefined; } coolDown() { this.temperature = 'warm'; @@ -124,13 +123,13 @@ class Coffee { } const cappuccino = new Coffee(); -cappuccino.hasOwnProperty('temperature'); +Object.hasOwn(cappucino,'temperature'); // => true -cappuccino.hasOwnProperty('constructor'); +Object.hasOwn(cappucino,'constructor'); // => false -cappuccino.hasOwnProperty('coolDown'); +Object.hasOwn(cappucino,'coolDown'); // => false ``` From 50e4e948f927b19b539127041b72eb21e32289f8 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:33:15 +0200 Subject: [PATCH 039/146] Update introduction.md --- concepts/type-checking/introduction.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index c80f2bb781..72ec4ebaaa 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -108,15 +108,14 @@ const espresso = new Coffee(); To avoid this, use the hasOwnProperty() method. ```` -## The `hasOwnProperty()` method +## The `Object.hasOwn()` function -The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. ```javascript class Coffee { constructor() { this.temperature = 'hot'; - this.isDarkMatter = undefined; } coolDown() { this.temperature = 'warm'; @@ -124,13 +123,13 @@ class Coffee { } const cappuccino = new Coffee(); -cappuccino.hasOwnProperty('temperature'); +Object.hasOwn(cappucino,'temperature'); // => true -cappuccino.hasOwnProperty('constructor'); +Object.hasOwn(cappucino,'constructor'); // => false -cappuccino.hasOwnProperty('coolDown'); +Object.hasOwn(cappucino,'coolDown'); // => false ``` From 3cdcf383e36512d8c23213a808a8250877bf34d4 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:33:37 +0200 Subject: [PATCH 040/146] Update about.md --- concepts/type-checking/about.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index c80f2bb781..72ec4ebaaa 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -108,15 +108,14 @@ const espresso = new Coffee(); To avoid this, use the hasOwnProperty() method. ```` -## The `hasOwnProperty()` method +## The `Object.hasOwn()` function -The `hasOwnProperty()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. ```javascript class Coffee { constructor() { this.temperature = 'hot'; - this.isDarkMatter = undefined; } coolDown() { this.temperature = 'warm'; @@ -124,13 +123,13 @@ class Coffee { } const cappuccino = new Coffee(); -cappuccino.hasOwnProperty('temperature'); +Object.hasOwn(cappucino,'temperature'); // => true -cappuccino.hasOwnProperty('constructor'); +Object.hasOwn(cappucino,'constructor'); // => false -cappuccino.hasOwnProperty('coolDown'); +Object.hasOwn(cappucino,'coolDown'); // => false ``` From cee3bb3d7e8e810bc0c62674571312957e18d425 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:44:36 +0200 Subject: [PATCH 041/146] Update assembly-line.spec.js Add tests for isBoolean --- .../concept/assembly-line/assembly-line.spec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index e69de29bb2..9f9dc74c72 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -0,0 +1,15 @@ +import { describe, expect, test } from '@jest/globals'; +import { isBoolean, isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , isEmptyArray, assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' +describe("isBoolean",() => { + test("isBoolean identifies booleans",() => { + expect(isBoolean(true)).toBe(true) + expect(isBoolean(false)).toBe(true) + }); + test("isBoolean identifies non-booleans",() => { + expect(isBoolean(42)).toBe(false) + expect(isBoolean("Hello, World!")).toBe(false) + expect(isBoolean(null)).toBe(false) + expect(isBoolean("")).toBe(false) + expect(isBoolean(Symbol("1"))).toBe(false) + }); +}); From ef5ff73b3dc1737222eed20652130cd24c0ef351 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:45:19 +0200 Subject: [PATCH 042/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 9f9dc74c72..6a5103fce7 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , isEmptyArray, assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' +import { isBoolean, isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' describe("isBoolean",() => { test("isBoolean identifies booleans",() => { expect(isBoolean(true)).toBe(true) From f7bfcf41db64907b5f9c17fe5371693aefca8851 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 14:46:06 +0200 Subject: [PATCH 043/146] Update assembly-line.spec.js Temporarily commented out some code. --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 6a5103fce7..7013153d6d 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' +import { isBoolean, /*isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' describe("isBoolean",() => { test("isBoolean identifies booleans",() => { expect(isBoolean(true)).toBe(true) From 1bd721bff6539126206292743790a8ff8af30e14 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 15:59:16 +0200 Subject: [PATCH 044/146] Add tests for isNumber --- .../assembly-line/assembly-line.spec.js | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 7013153d6d..639c7f567f 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,11 +1,11 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, /*isNumber, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' +import { isBoolean, isNumber/*, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' describe("isBoolean",() => { - test("isBoolean identifies booleans",() => { + test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) expect(isBoolean(false)).toBe(true) }); - test("isBoolean identifies non-booleans",() => { + test("isBoolean works on non-booleans",() => { expect(isBoolean(42)).toBe(false) expect(isBoolean("Hello, World!")).toBe(false) expect(isBoolean(null)).toBe(false) @@ -13,3 +13,26 @@ describe("isBoolean",() => { expect(isBoolean(Symbol("1"))).toBe(false) }); }); +describe("isNumber",() => { + test("isNumber works on numbers",() => { + expect(isNumber(42)).toBe(true) + expect(isNumber(92)).toBe(true) + expect(isNumber(43859435.12).toBe(true) + }); + test("isNumber works on bigints",() => { + expect(isNumber(42n)).toBe(true) + expect(isNumber(92n)).toBe(true) + expect(isNumber(1848958451n).toBe(true) + }); + test("isNumber works on non-numbers",() => { + expect(isNumber(true)).toBe(false) + expect(isNumber("Hello, World!")).toBe(false) + expect(isNumber(null)).toBe(false) + expect(isNumber("")).toBe(false) + expect(isNumber(Symbol("1"))).toBe(false) + }); + test("isNumber works on NaN and Infinity",() => { + expect(isNumber(NaN)).toBe(false) + expect(isNumber(Infinity)).toBe(false) + }) +}); From 4f586e169aac9926badb07f4120bda6d9bcc3442 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 16:07:11 +0200 Subject: [PATCH 045/146] Update assembly-line.spec.js --- .../concept/assembly-line/assembly-line.spec.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 639c7f567f..0d648c01c8 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -14,14 +14,14 @@ describe("isBoolean",() => { }); }); describe("isNumber",() => { - test("isNumber works on numbers",() => { - expect(isNumber(42)).toBe(true) - expect(isNumber(92)).toBe(true) - expect(isNumber(43859435.12).toBe(true) - }); + /*test("isNumber works on numbers",() => { + expect(isNumber(42)).toBe(true); + expect(isNumber(92)).toBe(true); + expect(isNumber(43859435.12).toBe(true); + });*/ test("isNumber works on bigints",() => { - expect(isNumber(42n)).toBe(true) - expect(isNumber(92n)).toBe(true) + expect(isNumber(42n)).toBe(true); + expect(isNumber(92n)).toBe(true); expect(isNumber(1848958451n).toBe(true) }); test("isNumber works on non-numbers",() => { From 988aafcb3b73668803b6b5fc196bd4271580280a Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 16:10:06 +0200 Subject: [PATCH 046/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 0d648c01c8..4c9c0a815b 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -14,15 +14,15 @@ describe("isBoolean",() => { }); }); describe("isNumber",() => { - /*test("isNumber works on numbers",() => { + test("isNumber works on numbers",() => { expect(isNumber(42)).toBe(true); expect(isNumber(92)).toBe(true); - expect(isNumber(43859435.12).toBe(true); - });*/ + expect(isNumber(43859435.12)).toBe(true); + }); test("isNumber works on bigints",() => { expect(isNumber(42n)).toBe(true); expect(isNumber(92n)).toBe(true); - expect(isNumber(1848958451n).toBe(true) + expect(isNumber(1848958451n)).toBe(true) }); test("isNumber works on non-numbers",() => { expect(isNumber(true)).toBe(false) From ef8e430c64e764379cf7c182eb2ffb11aa703ea0 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 16:11:05 +0200 Subject: [PATCH 047/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 3966968758..b7ce04d413 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -24,7 +24,7 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) + return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) && number !== Infinity } /** From c5b339cfc6670951323c0a8ca1c7095e2a708775 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 16:11:44 +0200 Subject: [PATCH 048/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index b7ce04d413..89a9c6ffea 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -24,7 +24,7 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) && number !== Infinity + return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) && value !== Infinity } /** From b1977ad9c68ffcbc1520713341fe5073554dd2ce Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 16:13:37 +0200 Subject: [PATCH 049/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 89a9c6ffea..bded5d467c 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -24,7 +24,7 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNaN(value) && value !== Infinity + return (typeof value === "number"||typeof value === "bigint") && !isNaN(Number(value)) && value !== Infinity } /** From 4057c80baf8fa46e79d30f0b80adfe572479e5ca Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 17:18:38 +0200 Subject: [PATCH 050/146] Update assembly-line.spec.js --- .../assembly-line/assembly-line.spec.js | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 4c9c0a815b..80ed22f620 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber/*, isObject, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' +import { isBoolean, isNumber, isObject/*, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' describe("isBoolean",() => { test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) @@ -36,3 +36,30 @@ describe("isNumber",() => { expect(isNumber(Infinity)).toBe(false) }) }); +class ClassForTestingisObject { + constructor(word){ + this.number=word + } +} +describe("isObject",() => { + test("isObject works on objects",() => { + expect(isObject({})).toBe(true); + expect(isObject({greeting:hello})).toBe(true); + }); + test("isObject works on classes",() => { + expect(isObject(new ClassForTestingisObject())).toBe(true); + expect(isObject(new ClassForTestingisObject())).toBe(true); + expect(isObject(new ClassForTestingisObject())).toBe(true) + }); + test("isObject works on non-Objects",() => { + expect(isObject(true)).toBe(false) + expect(isObject("Hello, World!")).toBe(false) + expect(isObject(null)).toBe(false) + expect(isObject("")).toBe(false) + expect(isObject(Symbol("1"))).toBe(false) + }); + test("isObject works on NaN and Infinity",() => { + expect(isObject(NaN)).toBe(false) + expect(isObject(Infinity)).toBe(false) + }) +}); From dbcc9cdd87a2ca03045096610dd75289ee529163 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 18:31:24 +0200 Subject: [PATCH 051/146] Update assembly-line.spec.js Add tests for isObject --- .../assembly-line/assembly-line.spec.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 80ed22f620..b108d0cefa 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -37,8 +37,9 @@ describe("isNumber",() => { }) }); class ClassForTestingisObject { - constructor(word){ - this.number=word + constructor(number,word){ + this.number = number; + this.word = word; } } describe("isObject",() => { @@ -46,20 +47,19 @@ describe("isObject",() => { expect(isObject({})).toBe(true); expect(isObject({greeting:hello})).toBe(true); }); - test("isObject works on classes",() => { - expect(isObject(new ClassForTestingisObject())).toBe(true); - expect(isObject(new ClassForTestingisObject())).toBe(true); - expect(isObject(new ClassForTestingisObject())).toBe(true) + test("isObject works on class instances",() => { + expect(isObject(new ClassForTestingisObject(5,"Hello"))).toBe(true); + expect(isObject(new ClassForTestingisObject(58,"null"))).toBe(true); + expect(isObject(new ClassForTestingisObject(1488,"World!"))).toBe(true) }); test("isObject works on non-Objects",() => { expect(isObject(true)).toBe(false) expect(isObject("Hello, World!")).toBe(false) - expect(isObject(null)).toBe(false) + expect(isObject(undefined)).toBe(false) expect(isObject("")).toBe(false) expect(isObject(Symbol("1"))).toBe(false) }); - test("isObject works on NaN and Infinity",() => { - expect(isObject(NaN)).toBe(false) - expect(isObject(Infinity)).toBe(false) + test("isObject works on null",() => { + expect(isObject(null)).toBe(false) }) }); From 8185213af08eadf2d1f08c283bac19a69518aef2 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 18:32:17 +0200 Subject: [PATCH 052/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index b108d0cefa..6982dfd0b7 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -45,7 +45,7 @@ class ClassForTestingisObject { describe("isObject",() => { test("isObject works on objects",() => { expect(isObject({})).toBe(true); - expect(isObject({greeting:hello})).toBe(true); + expect(isObject({greeting:"hello"})).toBe(true); }); test("isObject works on class instances",() => { expect(isObject(new ClassForTestingisObject(5,"Hello"))).toBe(true); From 895163c299bbda33f9776d6d36b84dd92aaf3886 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 18:49:53 +0200 Subject: [PATCH 053/146] Update assembly-line.spec.js Add tests for isNumericString --- .../assembly-line/assembly-line.spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 6982dfd0b7..69f10a09a0 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -63,3 +63,21 @@ describe("isObject",() => { expect(isObject(null)).toBe(false) }) }); +describe("isNumericString",() => { + test("isNumericString works on numeric strings",() => { + expect(isNumericString("42")).toBe(true); + expect(isNumericString("582")).toBe(true); + }); + test("isNumericString works on non-numeric strings",() => { + expect(isNumericString("Hello, World!")).toBe(false); + expect(isNumericString("")).toBe(false); + expect(isNumericString("NaN")).toBe(false) + }); + test("isNumericString works on non-strings",() => { + expect(isNumericString(true)).toBe(false) + expect(isNumericString(1234)).toBe(false) + expect(isNumericString(undefined)).toBe(false) + expect(isNumericString([1,2,3,4])).toBe(false) + expect(isNumericString(Symbol("\u0070"))).toBe(false) + }); +}); From 0033bd6ec99175d4065cc1c099e1c80ae0a3b27b Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 18:50:34 +0200 Subject: [PATCH 054/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 69f10a09a0..15fdd8dcdf 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject/*, isNumericString, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' +import { isBoolean, isNumber, isObject, isNumericString/*, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' describe("isBoolean",() => { test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) From 0d884ac9784bf9ac225c526fb5fa4e118b612aca Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 18:58:54 +0200 Subject: [PATCH 055/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index bded5d467c..bbf4533b40 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -44,7 +44,7 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return isNumber(Number(value)) + return typeof value === "string" && value.every((char) => {char.test(/\d/)}) } /** From 265ea06cd9227e83bebbed1cc7883df2093bc106 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:01:21 +0200 Subject: [PATCH 056/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index bbf4533b40..cd369e9d42 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -44,7 +44,7 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return typeof value === "string" && value.every((char) => {char.test(/\d/)}) + return typeof value === "string" && value.split("").every((char) => {char.test(/\d/)}) } /** From 7f8b489231d7abf0acc4006596902b1c0fac80fa Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:02:51 +0200 Subject: [PATCH 057/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index cd369e9d42..91f4ba65e6 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -44,7 +44,7 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return typeof value === "string" && value.split("").every((char) => {char.test(/\d/)}) + return typeof value === "string" && value.split("").every((char) => {/\d/.test(char)}) } /** From b887fd52d9cab526b730ec0852dccf86ee1bfc74 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:04:19 +0200 Subject: [PATCH 058/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 91f4ba65e6..041c4da397 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -44,7 +44,7 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return typeof value === "string" && value.split("").every((char) => {/\d/.test(char)}) + return typeof value === "string" && value.split("").every((char) => {/[0-9]/.test(char)}) } /** From 84b94b1377a27b2607249c13d062a18dbbc93354 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:07:19 +0200 Subject: [PATCH 059/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 041c4da397..db310b330a 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -44,7 +44,7 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return typeof value === "string" && value.split("").every((char) => {/[0-9]/.test(char)}) + return typeof value === "string" && value.split("").every((char) => {return /[0-9]/.test(char)}) } /** From 1ce83b22c048c10ad2b16a2ba56ba7d0f361b9d0 Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:09:51 +0200 Subject: [PATCH 060/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index db310b330a..0df7c539b5 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -4,7 +4,7 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -class ElectronicDevice { +export class ElectronicDevice { // This class will be used in the exercise. } /** From 6bedc110fc12de525f4c4ffc3c66551ca11db86d Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:10:12 +0200 Subject: [PATCH 061/146] Update assembly-line.js --- exercises/concept/assembly-line/assembly-line.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index eb3edc71fe..6cdcf9acfb 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -4,7 +4,7 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -class ElectronicDevice { +export class ElectronicDevice { // This class will be used in the exercise. } /** From 261e932d438c96330322dedcdd10173fb97e613d Mon Sep 17 00:00:00 2001 From: J R M Date: Sat, 28 Jun 2025 19:12:21 +0200 Subject: [PATCH 062/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 15fdd8dcdf..7d5419fee6 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString/*, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' +import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic/*, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' describe("isBoolean",() => { test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) From c2fd423432a703bf1171a4be2907a3320dac986b Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 10:53:42 +0200 Subject: [PATCH 063/146] Update about.md Added note about TS --- concepts/type-checking/about.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 72ec4ebaaa..7eefe10d08 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -3,7 +3,11 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. +~~~~exercism/note +Javascript's type checking mechanisms are always soomewhat unreliable. +For true safety with types, you should probably use [TypeScript][TS], a language built on to JavaScript, but with the type syntax of a static-typed language. +~~~~ ## The `typeof` operator The `typeof` operator returns the type of its input. @@ -133,6 +137,7 @@ Object.hasOwn(cappucino,'coolDown'); // => false ``` +[TS]: https://www.typescriptlang.org/ [primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive [typeof null is object]: https://2ality.com/2013/10/typeof-null.html [prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From befc340c2d8600ad4add96962eaec9b85f527dcc Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 10:55:42 +0200 Subject: [PATCH 064/146] Update introduction.md --- concepts/type-checking/introduction.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index 72ec4ebaaa..df5e4d5ce9 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -3,7 +3,11 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. +~~~~exercism/note +Javascript's type checking mechanisms are always soomewhat unreliable. +For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +~~~~ ## The `typeof` operator The `typeof` operator returns the type of its input. From 586bac3cf67bb1d774185a9cd774829f1f30602b Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 10:56:04 +0200 Subject: [PATCH 065/146] Update about.md --- concepts/type-checking/about.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 7eefe10d08..df5e4d5ce9 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -6,7 +6,7 @@ Javascript has several ways to check the type of an object. ~~~~exercism/note Javascript's type checking mechanisms are always soomewhat unreliable. -For true safety with types, you should probably use [TypeScript][TS], a language built on to JavaScript, but with the type syntax of a static-typed language. +For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. ~~~~ ## The `typeof` operator @@ -137,7 +137,6 @@ Object.hasOwn(cappucino,'coolDown'); // => false ``` -[TS]: https://www.typescriptlang.org/ [primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive [typeof null is object]: https://2ality.com/2013/10/typeof-null.html [prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain From 033a779956d04d59cb68fd0329da385a0d16ed68 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 10:56:30 +0200 Subject: [PATCH 066/146] Update introduction.md --- exercises/concept/assembly-line/.docs/introduction.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/introduction.md b/exercises/concept/assembly-line/.docs/introduction.md index 5251310995..73c820b79c 100644 --- a/exercises/concept/assembly-line/.docs/introduction.md +++ b/exercises/concept/assembly-line/.docs/introduction.md @@ -3,7 +3,11 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. +~~~~exercism/note +Javascript's type checking mechanisms are always soomewhat unreliable. +For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +~~~~ ## The `typeof` operator The `typeof` operator returns the type of its input. From 0e8901dfe2f21e114aae2f25ed294b287a17ba05 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 11:09:30 +0200 Subject: [PATCH 067/146] Update assembly-line.spec.js Add tests for isElectronic --- .../assembly-line/assembly-line.spec.js | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 7d5419fee6..4e1828fc56 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -36,7 +36,7 @@ describe("isNumber",() => { expect(isNumber(Infinity)).toBe(false) }) }); -class ClassForTestingisObject { +class ClassForTesting { constructor(number,word){ this.number = number; this.word = word; @@ -48,9 +48,9 @@ describe("isObject",() => { expect(isObject({greeting:"hello"})).toBe(true); }); test("isObject works on class instances",() => { - expect(isObject(new ClassForTestingisObject(5,"Hello"))).toBe(true); - expect(isObject(new ClassForTestingisObject(58,"null"))).toBe(true); - expect(isObject(new ClassForTestingisObject(1488,"World!"))).toBe(true) + expect(isObject(new ClassForTesting(5,"Hello"))).toBe(true); + expect(isObject(new ClassForTesting(58,"null"))).toBe(true); + expect(isObject(new ClassForTesting(1488,"World!"))).toBe(true) }); test("isObject works on non-Objects",() => { expect(isObject(true)).toBe(false) @@ -81,3 +81,28 @@ describe("isNumericString",() => { expect(isNumericString(Symbol("\u0070"))).toBe(false) }); }); +class Oven extends ElectronicDevice {} +class Computer extends ElectronicDevice {} +class PC extends Computer {} +class HomeMadePC extends PC {} +describe("isElectronic",() => { + test("isElectronic works on instances of ElectronicDevice or its child classes",() => { + expect(isElectronic(new ElectronicDevice())).toBe(true); + expect(isElectronic(new Oven())).toBe(true); + }); + test("isElectronic works on other objects",() => { + expect(isElectronic({language:"javascript", typing:"dynamic"})).toBe(false); + expect(isElectronic(new ClassForTesting(42, "ElectronicDevice"))).toBe(false); + expect(isElectronic([1,2,3,4])).toBe(false) + }); + test("isElectronic works on non-objects",() => { + expect(isElectronic(true)).toBe(false) + expect(isElectronic(1234)).toBe(false) + expect(isElectronic(undefined)).toBe(false) + expect(isElectronic("Hello!")).toBe(false) + expect(isElectronic(Symbol("\u0070"))).toBe(false) + }); + test("a really long prototype chain",()=>{ + expect(isElectronic(new HomeMadePC())).toBe(true) + }); +}); From 7e5b49d8d7164077a2ee5e6d290d7125bf93cf4d Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 17:47:20 +0200 Subject: [PATCH 068/146] Update assembly-line.spec.js --- .../assembly-line/assembly-line.spec.js | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 4e1828fc56..fe8153f98e 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -106,3 +106,64 @@ describe("isElectronic",() => { expect(isElectronic(new HomeMadePC())).toBe(true) }); }); +describe("isNonEmptyArray", () => { + test("isNonEmptyArray works on non-empty arrays", () => { + expect(isNonEmptyArray([1, 2, 3])).toBe(true); + expect(isNonEmptyArray(['a', 'b'])).toBe(true); + }); + test("isNonEmptyArray works on empty arrays", () => { + expect(isNonEmptyArray([])).toBe(false); + }); + test("isNonEmptyArray works on non-arrays", () => { + expect(isNonEmptyArray({})).toBe(false); + expect(isNonEmptyArray("string")).toBe(false); + expect(isNonEmptyArray(123)).toBe(false); + }); +}); + +describe("isEmptyArray", () => { + test("isEmptyArray works on empty arrays", () => { + expect(isEmptyArray([])).toBe(true); + }); + test("isEmptyArray works on non-empty arrays", () => { + expect(isEmptyArray([1, 2, 3])).toBe(false); + }); + test("isEmptyArray works on non-arrays", () => { + expect(isEmptyArray({})).toBe(false); + expect(isEmptyArray("string")).toBe(false); + expect(isEmptyArray(123)).toBe(false); + }); +}); + +describe("assertHasId", () => { + test("assertHasId throws error if object has no 'id' property", () => { + expect(() => assertHasId({})).toThrow("Object must have an 'id' property"); + }); + test("assertHasId does not throw error if object has 'id' property", () => { + expect(() => assertHasId({ id: 1 })).not.toThrow(); + }); +}); + +describe("hasType", () => { + test("hasType works correctly", () => { + expect(hasType({ type: 'example' })).toBe(true); + expect(hasType({})).toBe(false); + }); +}); + +describe("hasConstructorProperty", () => { + test("hasConstructorProperty works correctly", () => { + expect(hasConstructorProperty({ constructor: 'test' })).toBe(true); + expect(hasConstructorProperty({})).toBe(false); + expect(hasConstructorProperty(new ClassForTesting)).toBe(false); + + }); +}); + +describe("hasDefinedType", () => { + test("hasDefinedType works correctly", () => { + expect(hasDefinedType({ type: 'example' })).toBe(true); + expect(hasDefinedType({ type: undefined })).toBe(false); + expect(hasDefinedType({})).toBe(false); + }); +}); From 55d78f6198757aa9c29a3bfbbfdf523d002bdeba Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 17:48:59 +0200 Subject: [PATCH 069/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index fe8153f98e..ef5b0711b9 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic/*, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType*/} from './assembly-line' +import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' describe("isBoolean",() => { test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) From 7b1bb6a1163eea47e2d3f323e2dd47ed79ba0299 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 17:51:48 +0200 Subject: [PATCH 070/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 0df7c539b5..1c936041c5 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -64,7 +64,7 @@ export function isElectronic(object) { * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { - return value instanceof Array && value.length < 0 + return value instanceof Array && value.length > 0 } /** From d561f4095cce757b8b1c66b07839fddecabff5f7 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 17:51:57 +0200 Subject: [PATCH 071/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index ef5b0711b9..506b1f7371 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -137,7 +137,7 @@ describe("isEmptyArray", () => { describe("assertHasId", () => { test("assertHasId throws error if object has no 'id' property", () => { - expect(() => assertHasId({})).toThrow("Object must have an 'id' property"); + expect(() => assertHasId({})).toThrow(); }); test("assertHasId does not throw error if object has 'id' property", () => { expect(() => assertHasId({ id: 1 })).not.toThrow(); From b2051def00c04cf8a0a94bd0752d615bf0dfff32 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 19:45:25 +0200 Subject: [PATCH 072/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 506b1f7371..73fd89ed7c 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -83,8 +83,8 @@ describe("isNumericString",() => { }); class Oven extends ElectronicDevice {} class Computer extends ElectronicDevice {} -class PC extends Computer {} -class HomeMadePC extends PC {} +class PersonalComputer extends Computer {} +class HomeMadePersonalComputer extends PersonalComputer {} describe("isElectronic",() => { test("isElectronic works on instances of ElectronicDevice or its child classes",() => { expect(isElectronic(new ElectronicDevice())).toBe(true); From 628394239faa2b1a389a753e8b2609bf3c80e724 Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 19:51:58 +0200 Subject: [PATCH 073/146] Update hints.md Most of it is still copied from instructions --- .../concept/assembly-line/.docs/hints.md | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/assembly-line/.docs/hints.md index e69de29bb2..ce4ff4be18 100644 --- a/exercises/concept/assembly-line/.docs/hints.md +++ b/exercises/concept/assembly-line/.docs/hints.md @@ -0,0 +1,142 @@ +# Hints + + +## 1. Check if a value is a boolean + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. + +## 2. Check if a value is a number. + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- `NaN` is never equal to itself + +## 3. Check if a value is an object + +Implement the `isObject` function, that should check if the value is actually an object, not null. + +```javascript +isObject({greeting:"Hello"}) +// => true + +isObject(25n) +// => false +``` + +## 4. Check if a string is numeric + +Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. + +```javascript +isNumericString(42) +// => false + +isNumericString("42") +// => true + +isNumericString("Hi!") +// => false + +``` + +## 5. Check if an object is electronic + +Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. + +```javascript +class Duck { + //... +} +class WashingMachine extends ElectronicDevice { + //... +} +isElectronic(new Duck()) +// => false + +isElectronic(new WashingMachine()) +// => false +``` + +## 6. Check if a value is a non empty array + +Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. + +```javascript +isNonEmptyArray([1,2,3]) +// => true + +isNonEmptyArray([]) +// => false +``` + +## 7. Check if a value is an empty array + +Implement the `isEmptyArray` function, that checks if an object is an empty array. +```javascript +isEmptyArray([1,2,3]) +// => false + +isEmptyArray([]) +// => true +``` + +## 8. Throw an error if an object does not have the `id` property + +Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. + +If an object does have the `id` property, it should not return anything. + +```javascript +assertHasId({id:42,color:"red"}) +// => undefined + +assertHasId({color:"green"}) +// Error: "Object is missing the 'id' property" +``` + +## 9. Check if an object has a `type` property + +Implement the `hasType` function, that checks whether an object has a `type` property. + +```javascript +hasType({type:"car",color:"red"}) +// => true + +hasType({color:"green"}) +// => false +``` + +## 10. Check if an object has a `constructor` property + +Implement the `hasConstructorProperty` function, that checks whether an object has a `constructor` property. + +```javascript +class MyClass { + constructor() { + this.number = "42" + } +} +class MyNewClass { + constructor() { + this.number = "42" + this.constructor = "A constructor" + } +} +hasConstructorProperty(MyClass) +// => false + +hasConstructorProperty(MyNewClass) +// => true +``` +## 11. Check if an object has a defined `type` property + +Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. + +```javascript +hasDefinedType({type:undefined,color:"red"}) +// => false + +hasDefinedType({type:"car",color:"green"}) +// => true +``` From f2ce44c2a3070638a8ce2e456462526dbc2d6eff Mon Sep 17 00:00:00 2001 From: J R M Date: Sun, 29 Jun 2025 20:23:03 +0200 Subject: [PATCH 074/146] Update hints.md --- .../concept/assembly-line/.docs/hints.md | 49 +++++-------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/assembly-line/.docs/hints.md index ce4ff4be18..adda10da2c 100644 --- a/exercises/concept/assembly-line/.docs/hints.md +++ b/exercises/concept/assembly-line/.docs/hints.md @@ -10,53 +10,24 @@ - You can use `typeof` to find the type of a value. - `typeof` returns a string. -- `NaN` is never equal to itself +- You need to check for `Infinity` and `NaN`. +- `NaN` is never equal to itself, but there is a [built in function][isNaN] to check if a value is NaN. ## 3. Check if a value is an object -Implement the `isObject` function, that should check if the value is actually an object, not null. - -```javascript -isObject({greeting:"Hello"}) -// => true - -isObject(25n) -// => false -``` +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You will need to check for `null`. ## 4. Check if a string is numeric -Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. - -```javascript -isNumericString(42) -// => false - -isNumericString("42") -// => true - -isNumericString("Hi!") -// => false - -``` +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can iterate over a string to check if all characters are digits. ## 5. Check if an object is electronic -Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. - -```javascript -class Duck { - //... -} -class WashingMachine extends ElectronicDevice { - //... -} -isElectronic(new Duck()) -// => false - -isElectronic(new WashingMachine()) -// => false -``` +- You can use `instanceof` to check if an object is an instance of a class or one of its children. ## 6. Check if a value is a non empty array @@ -140,3 +111,5 @@ hasDefinedType({type:undefined,color:"red"}) hasDefinedType({type:"car",color:"green"}) // => true ``` + +[isNaN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN From 7b0104286554ac9f61ffc501e23b216cb230027c Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 09:52:19 +0200 Subject: [PATCH 075/146] Update hints.md --- .../concept/assembly-line/.docs/hints.md | 79 +++---------------- 1 file changed, 13 insertions(+), 66 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/assembly-line/.docs/hints.md index adda10da2c..6ddf8f05df 100644 --- a/exercises/concept/assembly-line/.docs/hints.md +++ b/exercises/concept/assembly-line/.docs/hints.md @@ -31,85 +31,32 @@ ## 6. Check if a value is a non empty array -Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. - -```javascript -isNonEmptyArray([1,2,3]) -// => true - -isNonEmptyArray([]) -// => false -``` +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can check the length of an array to find out how many elements it contains. ## 7. Check if a value is an empty array -Implement the `isEmptyArray` function, that checks if an object is an empty array. -```javascript -isEmptyArray([1,2,3]) -// => false - -isEmptyArray([]) -// => true -``` +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can check the length of an array to find out how many elements it contains. ## 8. Throw an error if an object does not have the `id` property -Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. - -If an object does have the `id` property, it should not return anything. - -```javascript -assertHasId({id:42,color:"red"}) -// => undefined - -assertHasId({color:"green"}) -// Error: "Object is missing the 'id' property" -``` +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- If the `id` property is missing, your function should throw an `Error`. ## 9. Check if an object has a `type` property -Implement the `hasType` function, that checks whether an object has a `type` property. - -```javascript -hasType({type:"car",color:"red"}) -// => true - -hasType({color:"green"}) -// => false -``` +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. ## 10. Check if an object has a `constructor` property -Implement the `hasConstructorProperty` function, that checks whether an object has a `constructor` property. - -```javascript -class MyClass { - constructor() { - this.number = "42" - } -} -class MyNewClass { - constructor() { - this.number = "42" - this.constructor = "A constructor" - } -} -hasConstructorProperty(MyClass) -// => false - -hasConstructorProperty(MyNewClass) -// => true -``` -## 11. Check if an object has a defined `type` property - -Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. +- All class instances have a `constructor`, but `Object.hasOwn()` is able to ignore this. -```javascript -hasDefinedType({type:undefined,color:"red"}) -// => false +## 11. Check if an object has a defined `type` property -hasDefinedType({type:"car",color:"green"}) -// => true -``` +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- You will have to access the `type` property and check if it is defined. [isNaN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN From b906c42b98266be4deb02ceb960ea3742cc1690f Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 09:55:47 +0200 Subject: [PATCH 076/146] Update instructions.md --- exercises/concept/assembly-line/.docs/instructions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index be45da5328..08737ee529 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -4,6 +4,10 @@ You have been hired by a company that makes various products. Due to lack of space, all the products are made on the same assembly line, but this has lead to products exiting the factory as unusable piles of metal, glass, and wood. To fix this, you have been tasked with making functions to identify the type of a product. +~~~~exercism/note +Many of the later tasks in this exercise can be solved using either `in` or `Object.hasOwn()`. +To practice, try to solve them with a mix of both. +~~~~ ### 1. Check if a value is a boolean Implement the `isBoolean` function, that checks if a value is a boolean. From 30915cf6af2a9f4944a2f268665ae23e5252539f Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 10:00:52 +0200 Subject: [PATCH 077/146] Update assembly-line.spec.js --- exercises/concept/assembly-line/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index 73fd89ed7c..abf99c03d5 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -103,7 +103,7 @@ describe("isElectronic",() => { expect(isElectronic(Symbol("\u0070"))).toBe(false) }); test("a really long prototype chain",()=>{ - expect(isElectronic(new HomeMadePC())).toBe(true) + expect(isElectronic(new HomeMadePersonalComputer())).toBe(true) }); }); describe("isNonEmptyArray", () => { From 5abc5c3453c7935a04886f097cbe695e0929c008 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:08:41 +0200 Subject: [PATCH 078/146] Update instructions.md --- .../concept/assembly-line/.docs/instructions.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index 08737ee529..e2d2b7c0a3 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -124,19 +124,27 @@ assertHasId({color:"green"}) // Error: "Object is missing the 'id' property" ``` -### 9. Check if an object has a `type` property +### 9. Check if an object has a `type` property or method -Implement the `hasType` function, that checks whether an object has a `type` property. +Implement the `hasType` function, that checks whether an object has a `type` property or method. ```javascript +class Keyboard(){ + type(){ + // ... + } +} hasType({type:"car",color:"red"}) // => true hasType({color:"green"}) // => false + +hasType(new Keyboard()) +// => true ``` -### 10. Check if an object has a `constructor` property +### 10. Check if an object has an `id` property Implement the `hasConstructorProperty` function, that checks whether an object has a `constructor` property. From 68f8402c5312b6e843e378005ba92c60d2f52926 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:32:02 +0200 Subject: [PATCH 079/146] Update instructions.md --- .../assembly-line/.docs/instructions.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/assembly-line/.docs/instructions.md index e2d2b7c0a3..c26a04b353 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/assembly-line/.docs/instructions.md @@ -110,7 +110,7 @@ isEmptyArray([]) // => true ``` -### 8. Throw an error if an object does not have the `id` property +### 8. Throw an error if an object does not have an `id` property or method Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. @@ -146,25 +146,29 @@ hasType(new Keyboard()) ### 10. Check if an object has an `id` property -Implement the `hasConstructorProperty` function, that checks whether an object has a `constructor` property. +Implement the `hasIdProperty` function, that checks whether an object has a `constructor` property. ```javascript class MyClass { constructor() { this.number = "42" + this.id = "BC269327FE1D9B95" } } class MyNewClass { constructor() { this.number = "42" - this.constructor = "A constructor" + this._id = "BC269327FE1D9B95" + } + get id(){ + return this._id } } -hasConstructorProperty(MyClass) -// => false - -hasConstructorProperty(MyNewClass) +hasIdProperty(new MyClass()) // => true + +hasIdProperty(new MyNewClass()) +// => false ``` ### 11. Check if an object has a defined `type` property From d501307641a14ab434e1bbc198e6f349f304f084 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:35:18 +0200 Subject: [PATCH 080/146] Update assembly-line.js --- exercises/concept/assembly-line/assembly-line.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/assembly-line/assembly-line.js index 6cdcf9acfb..69790e98ad 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/assembly-line/assembly-line.js @@ -78,33 +78,33 @@ export function isEmptyArray(value) { } /** - * Throws an error if an object is missing an "id" property. + * Throws an error if an object is missing an "id" property or method. * * @param {object} object - * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. + * @returns {undefined} undefined if the input has an "id" property or method, otherwise throws an error. */ export function assertHasId(object) { throw new Error("Remove this line and implement the assertHasId function") } /** - * Checks if a value has a "type" property. + * Checks if a value has a "type" property or method. * * @param {object} object - * @returns {boolean} whether the input has a "type" property. + * @returns {boolean} whether the input has a "type" property or method. */ export function hasType(object) { throw new Error("Remove this line and implement the hasType function") } /** - * Checks if a value has a "constructor" property. + * Checks if a value has an "id" property. * * @param {object} object - * @returns {boolean} whether the input has a "constructor" property. + * @returns {boolean} whether the input has an "id" property. */ -export function hasConstructorProperty(object) { - throw new Error("Remove this line and implement the hasConstructorProperty function") +export function hasIdProperty(object) { + throw new Error("Remove this line and implement the hasIdProperty function") } /** From 3109d6d81fdc334c991c22975e6219c715d441c1 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:36:48 +0200 Subject: [PATCH 081/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 1c936041c5..9fbfb84b86 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -78,7 +78,7 @@ export function isEmptyArray(value) { } /** - * Throws an error if an object is missing an "id" property. + * Throws an error if an object is missing an "id" property or method. * * @param {object} object * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. @@ -91,7 +91,7 @@ export function assertHasId(object) { } /** - * Checks if a value has a "type" property. + * Checks if a value has a "type" property or method. * * @param {object} object * @returns {boolean} whether the input has a "type" property. @@ -101,13 +101,13 @@ export function hasType(object) { } /** - * Checks if a value has a "constructor" property. + * Checks if a value has a "id" property. * * @param {object} object - * @returns {boolean} whether the input has a "constructor" property. + * @returns {boolean} whether the input has a "id" property. */ export function hasConstructorProperty(object) { - return Object.hasOwn(object,"constructor") + return Object.hasOwn(object,"id") } /** @@ -117,5 +117,5 @@ export function hasConstructorProperty(object) { * @returns {boolean} whether the input has a defined "type" property. */ export function hasDefinedType(object) { - return hasType(object) && object.type !== undefined + return Object.hasOwn(object, "type") && object.type !== undefined } From 45d740787e090757b804a7765ac51cd134c94407 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:37:36 +0200 Subject: [PATCH 082/146] Update exemplar.js --- exercises/concept/assembly-line/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/assembly-line/.meta/exemplar.js index 9fbfb84b86..7264d3be68 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/assembly-line/.meta/exemplar.js @@ -106,7 +106,7 @@ export function hasType(object) { * @param {object} object * @returns {boolean} whether the input has a "id" property. */ -export function hasConstructorProperty(object) { +export function hasIdProperty(object) { return Object.hasOwn(object,"id") } From bbfc4a2bc486c4e022835c25be7636a1b585594f Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:41:36 +0200 Subject: [PATCH 083/146] Update assembly-line.spec.js --- .../assembly-line/assembly-line.spec.js | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/assembly-line/assembly-line.spec.js index abf99c03d5..72f206729e 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/assembly-line/assembly-line.spec.js @@ -1,5 +1,5 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasConstructorProperty, hasDefinedType} from './assembly-line' +import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasIdProperty, hasDefinedType} from './assembly-line' describe("isBoolean",() => { test("isBoolean works on booleans",() => { expect(isBoolean(true)).toBe(true) @@ -41,6 +41,7 @@ class ClassForTesting { this.number = number; this.word = word; } + id(){} } describe("isObject",() => { test("isObject works on objects",() => { @@ -134,28 +135,34 @@ describe("isEmptyArray", () => { expect(isEmptyArray(123)).toBe(false); }); }); - +class TestAssertHasId { + id(){} +} describe("assertHasId", () => { - test("assertHasId throws error if object has no 'id' property", () => { + test("assertHasId throws error if object has no 'id' property or method", () => { expect(() => assertHasId({})).toThrow(); }); - test("assertHasId does not throw error if object has 'id' property", () => { + test("assertHasId does not throw error if object has 'id' property or method", () => { expect(() => assertHasId({ id: 1 })).not.toThrow(); + expect(() => assertHasId(new TestAssertHasId())).not.toThrow(); }); }); - +class TestHasType { + type(){} +} describe("hasType", () => { test("hasType works correctly", () => { expect(hasType({ type: 'example' })).toBe(true); expect(hasType({})).toBe(false); + expect(hasType(new TestHasType())).toBe(true) }); }); -describe("hasConstructorProperty", () => { - test("hasConstructorProperty works correctly", () => { - expect(hasConstructorProperty({ constructor: 'test' })).toBe(true); - expect(hasConstructorProperty({})).toBe(false); - expect(hasConstructorProperty(new ClassForTesting)).toBe(false); +describe("hasIdProperty", () => { + test("hasIdProperty works correctly", () => { + expect(hasIdProperty({ id: 'test' })).toBe(true); + expect(hasIdProperty({})).toBe(false); + expect(hasIdProperty(new ClassForTesting())).toBe(false); }); }); From a0f87e6cb5e69349853a4b981902d5330f6571b2 Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 18:56:12 +0200 Subject: [PATCH 084/146] Update config.json --- config.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index ac24caf488..534453e0b6 100644 --- a/config.json +++ b/config.json @@ -439,13 +439,14 @@ }, { "slug": "assembly-line", - "name": "assembly-line", + "name": "Assembly Line", "uuid": "16114449-52fe-470e-af11-cf9dc3689a93", "concepts": [ "type-checking" ], "prerequisites": [ - "basics" + "basics", + "inheritance" ] } ], From f6ad93f0f7fc7280c9df1e257a88b650a737cabd Mon Sep 17 00:00:00 2001 From: J R M Date: Mon, 30 Jun 2025 19:56:28 +0200 Subject: [PATCH 085/146] rename Assembly Line to Recycling Robot --- config.json | 4 +- .../.docs/hints.md | 124 +++--- .../.docs/instructions.md | 366 +++++++++--------- .../.docs/introduction.md | 284 +++++++------- .../.gitignore | 0 .../.meta/config.json | 0 .../.meta/exemplar.js | 242 ++++++------ .../{assembly-line => recycling-robot}/.npmrc | 0 .../LICENSE | 0 .../assembly-line.js | 236 +++++------ .../assembly-line.spec.js | 352 ++++++++--------- .../babel.config.js | 0 .../eslint.config.mjs | 0 .../jest.config.js | 0 .../package.json | 0 15 files changed, 804 insertions(+), 804 deletions(-) rename exercises/concept/{assembly-line => recycling-robot}/.docs/hints.md (97%) rename exercises/concept/{assembly-line => recycling-robot}/.docs/instructions.md (90%) rename exercises/concept/{assembly-line => recycling-robot}/.docs/introduction.md (96%) rename exercises/concept/{assembly-line => recycling-robot}/.gitignore (100%) rename exercises/concept/{assembly-line => recycling-robot}/.meta/config.json (100%) rename exercises/concept/{assembly-line => recycling-robot}/.meta/exemplar.js (96%) rename exercises/concept/{assembly-line => recycling-robot}/.npmrc (100%) rename exercises/concept/{assembly-line => recycling-robot}/LICENSE (100%) rename exercises/concept/{assembly-line => recycling-robot}/assembly-line.js (96%) rename exercises/concept/{assembly-line => recycling-robot}/assembly-line.spec.js (97%) rename exercises/concept/{assembly-line => recycling-robot}/babel.config.js (100%) rename exercises/concept/{assembly-line => recycling-robot}/eslint.config.mjs (100%) rename exercises/concept/{assembly-line => recycling-robot}/jest.config.js (100%) rename exercises/concept/{assembly-line => recycling-robot}/package.json (100%) diff --git a/config.json b/config.json index 534453e0b6..bbaee41bf4 100644 --- a/config.json +++ b/config.json @@ -438,8 +438,8 @@ ] }, { - "slug": "assembly-line", - "name": "Assembly Line", + "slug": "recycling-robot", + "name": "Recycling Robot", "uuid": "16114449-52fe-470e-af11-cf9dc3689a93", "concepts": [ "type-checking" diff --git a/exercises/concept/assembly-line/.docs/hints.md b/exercises/concept/recycling-robot/.docs/hints.md similarity index 97% rename from exercises/concept/assembly-line/.docs/hints.md rename to exercises/concept/recycling-robot/.docs/hints.md index 6ddf8f05df..46f5dcd175 100644 --- a/exercises/concept/assembly-line/.docs/hints.md +++ b/exercises/concept/recycling-robot/.docs/hints.md @@ -1,62 +1,62 @@ -# Hints - - -## 1. Check if a value is a boolean - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. - -## 2. Check if a value is a number. - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. -- You need to check for `Infinity` and `NaN`. -- `NaN` is never equal to itself, but there is a [built in function][isNaN] to check if a value is NaN. - -## 3. Check if a value is an object - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. -- You will need to check for `null`. - -## 4. Check if a string is numeric - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. -- You can iterate over a string to check if all characters are digits. - -## 5. Check if an object is electronic - -- You can use `instanceof` to check if an object is an instance of a class or one of its children. - -## 6. Check if a value is a non empty array - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. -- You can check the length of an array to find out how many elements it contains. - -## 7. Check if a value is an empty array - -- You can use `typeof` to find the type of a value. -- `typeof` returns a string. -- You can check the length of an array to find out how many elements it contains. - -## 8. Throw an error if an object does not have the `id` property - -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. -- If the `id` property is missing, your function should throw an `Error`. - -## 9. Check if an object has a `type` property - -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. - -## 10. Check if an object has a `constructor` property - -- All class instances have a `constructor`, but `Object.hasOwn()` is able to ignore this. - -## 11. Check if an object has a defined `type` property - -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. -- You will have to access the `type` property and check if it is defined. - -[isNaN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN +# Hints + + +## 1. Check if a value is a boolean + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. + +## 2. Check if a value is a number. + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You need to check for `Infinity` and `NaN`. +- `NaN` is never equal to itself, but there is a [built in function][isNaN] to check if a value is NaN. + +## 3. Check if a value is an object + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You will need to check for `null`. + +## 4. Check if a string is numeric + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can iterate over a string to check if all characters are digits. + +## 5. Check if an object is electronic + +- You can use `instanceof` to check if an object is an instance of a class or one of its children. + +## 6. Check if a value is a non empty array + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can check the length of an array to find out how many elements it contains. + +## 7. Check if a value is an empty array + +- You can use `typeof` to find the type of a value. +- `typeof` returns a string. +- You can check the length of an array to find out how many elements it contains. + +## 8. Throw an error if an object does not have the `id` property + +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- If the `id` property is missing, your function should throw an `Error`. + +## 9. Check if an object has a `type` property + +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. + +## 10. Check if an object has a `constructor` property + +- All class instances have a `constructor`, but `Object.hasOwn()` is able to ignore this. + +## 11. Check if an object has a defined `type` property + +- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- You will have to access the `type` property and check if it is defined. + +[isNaN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN diff --git a/exercises/concept/assembly-line/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md similarity index 90% rename from exercises/concept/assembly-line/.docs/instructions.md rename to exercises/concept/recycling-robot/.docs/instructions.md index c26a04b353..e793c14a6a 100644 --- a/exercises/concept/assembly-line/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -1,183 +1,183 @@ -## Instructions - -You have been hired by a company that makes various products. -Due to lack of space, all the products are made on the same assembly line, but this has lead to products exiting the factory as unusable piles of metal, glass, and wood. -To fix this, you have been tasked with making functions to identify the type of a product. - -~~~~exercism/note -Many of the later tasks in this exercise can be solved using either `in` or `Object.hasOwn()`. -To practice, try to solve them with a mix of both. -~~~~ -### 1. Check if a value is a boolean - -Implement the `isBoolean` function, that checks if a value is a boolean. - -```javascript -isBoolean(true) -// => true - -isBoolean(null) -// => false -``` - -### 2. Check if a value is a number. - -Implement the `isNumber` function, that checks if a value is a _finite_ number or bigint, ie not `NaN` or `Infinity`. - -Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. -Your function should be able to correctly handle this as well. - -```javascript -isNumber(42) -// => true - -isNumber("Hello, World!") -// => false - -isNumber(42n) -// => true - -isNumber(NaN) -// => false -``` - -### 3. Check if a value is an object - -Implement the `isObject` function, that should check if the value is actually an object, not null. - -```javascript -isObject({greeting:"Hello"}) -// => true - -isObject(25n) -// => false -``` - -### 4. Check if a string is numeric - -Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. - -```javascript -isNumericString(42) -// => false - -isNumericString("42") -// => true - -isNumericString("Hi!") -// => false - -``` - -### 5. Check if an object is electronic - -Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. - -```javascript -class Duck { - //... -} -class WashingMachine extends ElectronicDevice { - //... -} -isElectronic(new Duck()) -// => false - -isElectronic(new WashingMachine()) -// => false -``` - -### 6. Check if a value is a non empty array - -Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. - -```javascript -isNonEmptyArray([1,2,3]) -// => true - -isNonEmptyArray([]) -// => false -``` - -### 7. Check if a value is an empty array - -Implement the `isEmptyArray` function, that checks if an object is an empty array. -```javascript -isEmptyArray([1,2,3]) -// => false - -isEmptyArray([]) -// => true -``` - -### 8. Throw an error if an object does not have an `id` property or method - -Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. - -If an object does have the `id` property, it should not return anything. - -```javascript -assertHasId({id:42,color:"red"}) -// => undefined - -assertHasId({color:"green"}) -// Error: "Object is missing the 'id' property" -``` - -### 9. Check if an object has a `type` property or method - -Implement the `hasType` function, that checks whether an object has a `type` property or method. - -```javascript -class Keyboard(){ - type(){ - // ... - } -} -hasType({type:"car",color:"red"}) -// => true - -hasType({color:"green"}) -// => false - -hasType(new Keyboard()) -// => true -``` - -### 10. Check if an object has an `id` property - -Implement the `hasIdProperty` function, that checks whether an object has a `constructor` property. - -```javascript -class MyClass { - constructor() { - this.number = "42" - this.id = "BC269327FE1D9B95" - } -} -class MyNewClass { - constructor() { - this.number = "42" - this._id = "BC269327FE1D9B95" - } - get id(){ - return this._id - } -} -hasIdProperty(new MyClass()) -// => true - -hasIdProperty(new MyNewClass()) -// => false -``` -### 11. Check if an object has a defined `type` property - -Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. - -```javascript -hasDefinedType({type:undefined,color:"red"}) -// => false - -hasDefinedType({type:"car",color:"green"}) -// => true -``` +## Instructions + +You have been hired by a recycling center. +Due to lack of space, all the products are put on the same conveyor belt, but this has lead to different materials mixing together, making them unusable. +To fix this, you have been tasked with making functions to identify the type of a product. + +~~~~exercism/note +Many of the later tasks in this exercise can be solved using either `in` or `Object.hasOwn()`. +To practice, try to solve them with a mix of both. +~~~~ +### 1. Check if a value is a boolean + +Implement the `isBoolean` function, that checks if a value is a boolean. + +```javascript +isBoolean(true) +// => true + +isBoolean(null) +// => false +``` + +### 2. Check if a value is a number. + +Implement the `isNumber` function, that checks if a value is a _finite_ number or bigint, ie not `NaN` or `Infinity`. + +Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. +Your function should be able to correctly handle this as well. + +```javascript +isNumber(42) +// => true + +isNumber("Hello, World!") +// => false + +isNumber(42n) +// => true + +isNumber(NaN) +// => false +``` + +### 3. Check if a value is an object + +Implement the `isObject` function, that should check if the value is actually an object, not null. + +```javascript +isObject({greeting:"Hello"}) +// => true + +isObject(25n) +// => false +``` + +### 4. Check if a string is numeric + +Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. + +```javascript +isNumericString(42) +// => false + +isNumericString("42") +// => true + +isNumericString("Hi!") +// => false + +``` + +### 5. Check if an object is electronic + +Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. + +```javascript +class Duck { + //... +} +class WashingMachine extends ElectronicDevice { + //... +} +isElectronic(new Duck()) +// => false + +isElectronic(new WashingMachine()) +// => false +``` + +### 6. Check if a value is a non empty array + +Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. + +```javascript +isNonEmptyArray([1,2,3]) +// => true + +isNonEmptyArray([]) +// => false +``` + +### 7. Check if a value is an empty array + +Implement the `isEmptyArray` function, that checks if an object is an empty array. +```javascript +isEmptyArray([1,2,3]) +// => false + +isEmptyArray([]) +// => true +``` + +### 8. Throw an error if an object does not have an `id` property or method + +Implement the `assertHasId` function, that will throw an `Error` if an object is missing the `id` property. + +If an object does have the `id` property, it should not return anything. + +```javascript +assertHasId({id:42,color:"red"}) +// => undefined + +assertHasId({color:"green"}) +// Error: "Object is missing the 'id' property" +``` + +### 9. Check if an object has a `type` property or method + +Implement the `hasType` function, that checks whether an object has a `type` property or method. + +```javascript +class Keyboard(){ + type(){ + // ... + } +} +hasType({type:"car",color:"red"}) +// => true + +hasType({color:"green"}) +// => false + +hasType(new Keyboard()) +// => true +``` + +### 10. Check if an object has an `id` property + +Implement the `hasIdProperty` function, that checks whether an object has a `constructor` property. + +```javascript +class MyClass { + constructor() { + this.number = "42" + this.id = "BC269327FE1D9B95" + } +} +class MyNewClass { + constructor() { + this.number = "42" + this._id = "BC269327FE1D9B95" + } + get id(){ + return this._id + } +} +hasIdProperty(new MyClass()) +// => true + +hasIdProperty(new MyNewClass()) +// => false +``` +### 11. Check if an object has a defined `type` property + +Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. + +```javascript +hasDefinedType({type:undefined,color:"red"}) +// => false + +hasDefinedType({type:"car",color:"green"}) +// => true +``` diff --git a/exercises/concept/assembly-line/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md similarity index 96% rename from exercises/concept/assembly-line/.docs/introduction.md rename to exercises/concept/recycling-robot/.docs/introduction.md index 73c820b79c..df5e4d5ce9 100644 --- a/exercises/concept/assembly-line/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -1,142 +1,142 @@ -# About - -Knowning what type an object has is often very important for code to run smoothly and without errors. - -Javascript has several ways to check the type of an object. -~~~~exercism/note -Javascript's type checking mechanisms are always soomewhat unreliable. - -For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. -~~~~ -## The `typeof` operator - -The `typeof` operator returns the type of its input. -The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. - -```javascript -typeof undefined; -// => "undefined" - -typeof true; -// => "boolean" - -typeof 42; -// => "number" - -typeof 'Hello, World!'; -// => "string" - -typeof function () { - return 'Hello, World'; -}; -// => "function" - -typeof [1, 2, 3, 4]; -// => "object" - -typeof { city: 'Stockholm', country: 'Sweden' }; -// => "object" -``` - -The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. - -## The `instanceof` operator - -For checking the type of an object, you can use the `instanceof` operator. -It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. -To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. -`instanceof` only works for compound data types, such as arrays and objects. - -```javascript -class Beverage { - // ... -} -// The Coffee class is a child of the Beverage class. -class Coffee extends Beverage { - // ... -} -const java = new Coffee(); - -java instanceof Coffee; -// => true - -java instanceof Beverage; -// => true -``` - -```exercism/advanced -The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. - -While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. - -This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. -`Array.isArray()` is capable of ignoring this, and should always be used when possible. -``` - -## The `in` operator - -The `in` operator returns whether the first operand is a property of the second operand. -It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. - -```javascript -class Coffee { - constructor() { - this.temperature = 'hot'; - this.isDarkMatter = undefined; - } - coolDown() { - this.temperature = 'warm'; - } -} -const espresso = new Coffee(); - -'temperature' in espresso; -// => true - -'color' in espresso; -// => false - -'isDarkMatter' in espresso; -// => true -``` - -````exercism/note -`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. -```javascript -"coolDown" in espresso -// => true - -"constructor" in espresso -// => true -``` -To avoid this, use the hasOwnProperty() method. -```` - -## The `Object.hasOwn()` function - -The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. - -```javascript -class Coffee { - constructor() { - this.temperature = 'hot'; - } - coolDown() { - this.temperature = 'warm'; - } -} -const cappuccino = new Coffee(); - -Object.hasOwn(cappucino,'temperature'); -// => true - -Object.hasOwn(cappucino,'constructor'); -// => false - -Object.hasOwn(cappucino,'coolDown'); -// => false -``` - -[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive -[typeof null is object]: https://2ality.com/2013/10/typeof-null.html -[prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain +# About + +Knowning what type an object has is often very important for code to run smoothly and without errors. + +Javascript has several ways to check the type of an object. +~~~~exercism/note +Javascript's type checking mechanisms are always soomewhat unreliable. + +For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +~~~~ +## The `typeof` operator + +The `typeof` operator returns the type of its input. +The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. + +```javascript +typeof undefined; +// => "undefined" + +typeof true; +// => "boolean" + +typeof 42; +// => "number" + +typeof 'Hello, World!'; +// => "string" + +typeof function () { + return 'Hello, World'; +}; +// => "function" + +typeof [1, 2, 3, 4]; +// => "object" + +typeof { city: 'Stockholm', country: 'Sweden' }; +// => "object" +``` + +The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. + +## The `instanceof` operator + +For checking the type of an object, you can use the `instanceof` operator. +It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. +`instanceof` only works for compound data types, such as arrays and objects. + +```javascript +class Beverage { + // ... +} +// The Coffee class is a child of the Beverage class. +class Coffee extends Beverage { + // ... +} +const java = new Coffee(); + +java instanceof Coffee; +// => true + +java instanceof Beverage; +// => true +``` + +```exercism/advanced +The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. + +While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. + +This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +`Array.isArray()` is capable of ignoring this, and should always be used when possible. +``` + +## The `in` operator + +The `in` operator returns whether the first operand is a property of the second operand. +It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + this.isDarkMatter = undefined; + } + coolDown() { + this.temperature = 'warm'; + } +} +const espresso = new Coffee(); + +'temperature' in espresso; +// => true + +'color' in espresso; +// => false + +'isDarkMatter' in espresso; +// => true +``` + +````exercism/note +`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +```javascript +"coolDown" in espresso +// => true + +"constructor" in espresso +// => true +``` +To avoid this, use the hasOwnProperty() method. +```` + +## The `Object.hasOwn()` function + +The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. + +```javascript +class Coffee { + constructor() { + this.temperature = 'hot'; + } + coolDown() { + this.temperature = 'warm'; + } +} +const cappuccino = new Coffee(); + +Object.hasOwn(cappucino,'temperature'); +// => true + +Object.hasOwn(cappucino,'constructor'); +// => false + +Object.hasOwn(cappucino,'coolDown'); +// => false +``` + +[primitives]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive +[typeof null is object]: https://2ality.com/2013/10/typeof-null.html +[prototype chain]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain diff --git a/exercises/concept/assembly-line/.gitignore b/exercises/concept/recycling-robot/.gitignore similarity index 100% rename from exercises/concept/assembly-line/.gitignore rename to exercises/concept/recycling-robot/.gitignore diff --git a/exercises/concept/assembly-line/.meta/config.json b/exercises/concept/recycling-robot/.meta/config.json similarity index 100% rename from exercises/concept/assembly-line/.meta/config.json rename to exercises/concept/recycling-robot/.meta/config.json diff --git a/exercises/concept/assembly-line/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js similarity index 96% rename from exercises/concept/assembly-line/.meta/exemplar.js rename to exercises/concept/recycling-robot/.meta/exemplar.js index 7264d3be68..791a20bd24 100644 --- a/exercises/concept/assembly-line/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -1,121 +1,121 @@ -// @ts-check -// -// The line above enables type checking for this file. Various IDEs interpret -// the @ts-check directive. It will give you helpful autocompletion when -// implementing this exercise. - -export class ElectronicDevice { - // This class will be used in the exercise. -} -/** - * Checks if input is a boolean. - * - * @param {any} value - * @returns {boolean} whether the input is a boolean - */ -export function isBoolean(value) { - return typeof value === "boolean" -} - -/** - * Checks if input is a finite number or bigint. - * - * @param {any} value - * @returns {boolean} whether the input is a finite number or bigint - */ -export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNaN(Number(value)) && value !== Infinity -} - -/** - * Checks if a value is an object. - * - * @param {any} value - * @returns {boolean} whether the input is an object. - */ -export function isObject(value) { - return value !== null && typeof value === "object" -} - -/** - * Checks if a value is a numeric string. - * - * @param {any} value - * @returns {boolean} whether the input is a numeric string. - */ -export function isNumericString(value) { - return typeof value === "string" && value.split("").every((char) => {return /[0-9]/.test(char)}) -} - -/** - * Checks if an object is an instance of the "ElectronicDevice" class or one of its children. - * - * @param {object} object - * @returns {boolean} whether the object is an instance of the "ElectronicDevice" class or one of its children. - */ -export function isElectronic(object) { - return object instanceof ElectronicDevice -} - -/** - * Checks if a value is a non empty array. - * - * @param {any} value - * @returns {boolean} whether the input is a non empty array. - */ -export function isNonEmptyArray(value) { - return value instanceof Array && value.length > 0 -} - -/** - * Checks if a value is an empty array. - * - * @param {any} value - * @returns {boolean} whether the input is an empty array. - */ -export function isEmptyArray(value) { - return value instanceof Array && value.length === 0 -} - -/** - * Throws an error if an object is missing an "id" property or method. - * - * @param {object} object - * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. - */ -export function assertHasId(object) { - if ("id" in object){ - return; - } - throw new Error('The "id" property is missing.') -} - -/** - * Checks if a value has a "type" property or method. - * - * @param {object} object - * @returns {boolean} whether the input has a "type" property. - */ -export function hasType(object) { - return "type" in object -} - -/** - * Checks if a value has a "id" property. - * - * @param {object} object - * @returns {boolean} whether the input has a "id" property. - */ -export function hasIdProperty(object) { - return Object.hasOwn(object,"id") -} - -/** - * Checks if a value has a defined "type" property. - * - * @param {object} object - * @returns {boolean} whether the input has a defined "type" property. - */ -export function hasDefinedType(object) { - return Object.hasOwn(object, "type") && object.type !== undefined -} +// @ts-check +// +// The line above enables type checking for this file. Various IDEs interpret +// the @ts-check directive. It will give you helpful autocompletion when +// implementing this exercise. + +export class ElectronicDevice { + // This class will be used in the exercise. +} +/** + * Checks if input is a boolean. + * + * @param {any} value + * @returns {boolean} whether the input is a boolean + */ +export function isBoolean(value) { + return typeof value === "boolean" +} + +/** + * Checks if input is a finite number or bigint. + * + * @param {any} value + * @returns {boolean} whether the input is a finite number or bigint + */ +export function isNumber(value) { + return (typeof value === "number"||typeof value === "bigint") && !isNaN(Number(value)) && value !== Infinity +} + +/** + * Checks if a value is an object. + * + * @param {any} value + * @returns {boolean} whether the input is an object. + */ +export function isObject(value) { + return value !== null && typeof value === "object" +} + +/** + * Checks if a value is a numeric string. + * + * @param {any} value + * @returns {boolean} whether the input is a numeric string. + */ +export function isNumericString(value) { + return typeof value === "string" && value.split("").every((char) => {return /[0-9]/.test(char)}) +} + +/** + * Checks if an object is an instance of the "ElectronicDevice" class or one of its children. + * + * @param {object} object + * @returns {boolean} whether the object is an instance of the "ElectronicDevice" class or one of its children. + */ +export function isElectronic(object) { + return object instanceof ElectronicDevice +} + +/** + * Checks if a value is a non empty array. + * + * @param {any} value + * @returns {boolean} whether the input is a non empty array. + */ +export function isNonEmptyArray(value) { + return value instanceof Array && value.length > 0 +} + +/** + * Checks if a value is an empty array. + * + * @param {any} value + * @returns {boolean} whether the input is an empty array. + */ +export function isEmptyArray(value) { + return value instanceof Array && value.length === 0 +} + +/** + * Throws an error if an object is missing an "id" property or method. + * + * @param {object} object + * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. + */ +export function assertHasId(object) { + if ("id" in object){ + return; + } + throw new Error('The "id" property is missing.') +} + +/** + * Checks if a value has a "type" property or method. + * + * @param {object} object + * @returns {boolean} whether the input has a "type" property. + */ +export function hasType(object) { + return "type" in object +} + +/** + * Checks if a value has a "id" property. + * + * @param {object} object + * @returns {boolean} whether the input has a "id" property. + */ +export function hasIdProperty(object) { + return Object.hasOwn(object,"id") +} + +/** + * Checks if a value has a defined "type" property. + * + * @param {object} object + * @returns {boolean} whether the input has a defined "type" property. + */ +export function hasDefinedType(object) { + return Object.hasOwn(object, "type") && object.type !== undefined +} diff --git a/exercises/concept/assembly-line/.npmrc b/exercises/concept/recycling-robot/.npmrc similarity index 100% rename from exercises/concept/assembly-line/.npmrc rename to exercises/concept/recycling-robot/.npmrc diff --git a/exercises/concept/assembly-line/LICENSE b/exercises/concept/recycling-robot/LICENSE similarity index 100% rename from exercises/concept/assembly-line/LICENSE rename to exercises/concept/recycling-robot/LICENSE diff --git a/exercises/concept/assembly-line/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js similarity index 96% rename from exercises/concept/assembly-line/assembly-line.js rename to exercises/concept/recycling-robot/assembly-line.js index 69790e98ad..794e298b2d 100644 --- a/exercises/concept/assembly-line/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -1,118 +1,118 @@ -// @ts-check -// -// The line above enables type checking for this file. Various IDEs interpret -// the @ts-check directive. It will give you helpful autocompletion when -// implementing this exercise. - -export class ElectronicDevice { - // This class will be used in the exercise. -} -/** - * Checks if input is a boolean. - * - * @param {any} value - * @returns {boolean} whether the input is a boolean - */ -export function isBoolean(value) { - throw new Error("Remove this line and implement the isBoolean function") -} - -/** - * Checks if input is a finite number or bigint. - * - * @param {any} value - * @returns {boolean} whether the input is a finite number or bigint - */ -export function isNumber(value) { - throw new Error("Remove this line and implement the isNumber function") -} - -/** - * Checks if a value is an object. - * - * @param {any} value - * @returns {boolean} whether the input is an object. - */ -export function isObject(value) { - throw new Error("Remove this line and implement the isObject function") -} - -/** - * Checks if a value is a numeric string. - * - * @param {any} value - * @returns {boolean} whether the input is a numeric string. - */ -export function isNumericString(value) { - throw new Error("Remove this line and implement the isNumericString function") -} - -/** - * Checks if an object is an instance of the `ElectronicDevice` class or one of its children. - * - * @param {object} object - * @returns {boolean} whether the object is an instance of the `ElectronicDevice` class or one of its children. - */ -export function isElectronic(object) { - throw new Error("Remove this line and implement the isElectronic function") -} - -/** - * Checks if a value is a non empty array. - * - * @param {any} value - * @returns {boolean} whether the input is a non empty array. - */ -export function isNonEmptyArray(value) { - throw new Error("Remove this line and implement the isNonEmptyArray function") -} - -/** - * Checks if a value is an empty array. - * - * @param {any} value - * @returns {boolean} whether the input is an empty array. - */ -export function isEmptyArray(value) { - throw new Error("Remove this line and implement the isEmptyArray function") -} - -/** - * Throws an error if an object is missing an "id" property or method. - * - * @param {object} object - * @returns {undefined} undefined if the input has an "id" property or method, otherwise throws an error. - */ -export function assertHasId(object) { - throw new Error("Remove this line and implement the assertHasId function") -} - -/** - * Checks if a value has a "type" property or method. - * - * @param {object} object - * @returns {boolean} whether the input has a "type" property or method. - */ -export function hasType(object) { - throw new Error("Remove this line and implement the hasType function") -} - -/** - * Checks if a value has an "id" property. - * - * @param {object} object - * @returns {boolean} whether the input has an "id" property. - */ -export function hasIdProperty(object) { - throw new Error("Remove this line and implement the hasIdProperty function") -} - -/** - * Checks if a value has a defined "type" property. - * - * @param {object} object - * @returns {boolean} whether the input has a defined "type" property. - */ -export function hasDefinedType(object) { - throw new Error("Remove this line and implement the hasDefinedType function") -} +// @ts-check +// +// The line above enables type checking for this file. Various IDEs interpret +// the @ts-check directive. It will give you helpful autocompletion when +// implementing this exercise. + +export class ElectronicDevice { + // This class will be used in the exercise. +} +/** + * Checks if input is a boolean. + * + * @param {any} value + * @returns {boolean} whether the input is a boolean + */ +export function isBoolean(value) { + throw new Error("Remove this line and implement the isBoolean function") +} + +/** + * Checks if input is a finite number or bigint. + * + * @param {any} value + * @returns {boolean} whether the input is a finite number or bigint + */ +export function isNumber(value) { + throw new Error("Remove this line and implement the isNumber function") +} + +/** + * Checks if a value is an object. + * + * @param {any} value + * @returns {boolean} whether the input is an object. + */ +export function isObject(value) { + throw new Error("Remove this line and implement the isObject function") +} + +/** + * Checks if a value is a numeric string. + * + * @param {any} value + * @returns {boolean} whether the input is a numeric string. + */ +export function isNumericString(value) { + throw new Error("Remove this line and implement the isNumericString function") +} + +/** + * Checks if an object is an instance of the `ElectronicDevice` class or one of its children. + * + * @param {object} object + * @returns {boolean} whether the object is an instance of the `ElectronicDevice` class or one of its children. + */ +export function isElectronic(object) { + throw new Error("Remove this line and implement the isElectronic function") +} + +/** + * Checks if a value is a non empty array. + * + * @param {any} value + * @returns {boolean} whether the input is a non empty array. + */ +export function isNonEmptyArray(value) { + throw new Error("Remove this line and implement the isNonEmptyArray function") +} + +/** + * Checks if a value is an empty array. + * + * @param {any} value + * @returns {boolean} whether the input is an empty array. + */ +export function isEmptyArray(value) { + throw new Error("Remove this line and implement the isEmptyArray function") +} + +/** + * Throws an error if an object is missing an "id" property or method. + * + * @param {object} object + * @returns {undefined} undefined if the input has an "id" property or method, otherwise throws an error. + */ +export function assertHasId(object) { + throw new Error("Remove this line and implement the assertHasId function") +} + +/** + * Checks if a value has a "type" property or method. + * + * @param {object} object + * @returns {boolean} whether the input has a "type" property or method. + */ +export function hasType(object) { + throw new Error("Remove this line and implement the hasType function") +} + +/** + * Checks if a value has an "id" property. + * + * @param {object} object + * @returns {boolean} whether the input has an "id" property. + */ +export function hasIdProperty(object) { + throw new Error("Remove this line and implement the hasIdProperty function") +} + +/** + * Checks if a value has a defined "type" property. + * + * @param {object} object + * @returns {boolean} whether the input has a defined "type" property. + */ +export function hasDefinedType(object) { + throw new Error("Remove this line and implement the hasDefinedType function") +} diff --git a/exercises/concept/assembly-line/assembly-line.spec.js b/exercises/concept/recycling-robot/assembly-line.spec.js similarity index 97% rename from exercises/concept/assembly-line/assembly-line.spec.js rename to exercises/concept/recycling-robot/assembly-line.spec.js index 72f206729e..8a8d097208 100644 --- a/exercises/concept/assembly-line/assembly-line.spec.js +++ b/exercises/concept/recycling-robot/assembly-line.spec.js @@ -1,176 +1,176 @@ -import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasIdProperty, hasDefinedType} from './assembly-line' -describe("isBoolean",() => { - test("isBoolean works on booleans",() => { - expect(isBoolean(true)).toBe(true) - expect(isBoolean(false)).toBe(true) - }); - test("isBoolean works on non-booleans",() => { - expect(isBoolean(42)).toBe(false) - expect(isBoolean("Hello, World!")).toBe(false) - expect(isBoolean(null)).toBe(false) - expect(isBoolean("")).toBe(false) - expect(isBoolean(Symbol("1"))).toBe(false) - }); -}); -describe("isNumber",() => { - test("isNumber works on numbers",() => { - expect(isNumber(42)).toBe(true); - expect(isNumber(92)).toBe(true); - expect(isNumber(43859435.12)).toBe(true); - }); - test("isNumber works on bigints",() => { - expect(isNumber(42n)).toBe(true); - expect(isNumber(92n)).toBe(true); - expect(isNumber(1848958451n)).toBe(true) - }); - test("isNumber works on non-numbers",() => { - expect(isNumber(true)).toBe(false) - expect(isNumber("Hello, World!")).toBe(false) - expect(isNumber(null)).toBe(false) - expect(isNumber("")).toBe(false) - expect(isNumber(Symbol("1"))).toBe(false) - }); - test("isNumber works on NaN and Infinity",() => { - expect(isNumber(NaN)).toBe(false) - expect(isNumber(Infinity)).toBe(false) - }) -}); -class ClassForTesting { - constructor(number,word){ - this.number = number; - this.word = word; - } - id(){} -} -describe("isObject",() => { - test("isObject works on objects",() => { - expect(isObject({})).toBe(true); - expect(isObject({greeting:"hello"})).toBe(true); - }); - test("isObject works on class instances",() => { - expect(isObject(new ClassForTesting(5,"Hello"))).toBe(true); - expect(isObject(new ClassForTesting(58,"null"))).toBe(true); - expect(isObject(new ClassForTesting(1488,"World!"))).toBe(true) - }); - test("isObject works on non-Objects",() => { - expect(isObject(true)).toBe(false) - expect(isObject("Hello, World!")).toBe(false) - expect(isObject(undefined)).toBe(false) - expect(isObject("")).toBe(false) - expect(isObject(Symbol("1"))).toBe(false) - }); - test("isObject works on null",() => { - expect(isObject(null)).toBe(false) - }) -}); -describe("isNumericString",() => { - test("isNumericString works on numeric strings",() => { - expect(isNumericString("42")).toBe(true); - expect(isNumericString("582")).toBe(true); - }); - test("isNumericString works on non-numeric strings",() => { - expect(isNumericString("Hello, World!")).toBe(false); - expect(isNumericString("")).toBe(false); - expect(isNumericString("NaN")).toBe(false) - }); - test("isNumericString works on non-strings",() => { - expect(isNumericString(true)).toBe(false) - expect(isNumericString(1234)).toBe(false) - expect(isNumericString(undefined)).toBe(false) - expect(isNumericString([1,2,3,4])).toBe(false) - expect(isNumericString(Symbol("\u0070"))).toBe(false) - }); -}); -class Oven extends ElectronicDevice {} -class Computer extends ElectronicDevice {} -class PersonalComputer extends Computer {} -class HomeMadePersonalComputer extends PersonalComputer {} -describe("isElectronic",() => { - test("isElectronic works on instances of ElectronicDevice or its child classes",() => { - expect(isElectronic(new ElectronicDevice())).toBe(true); - expect(isElectronic(new Oven())).toBe(true); - }); - test("isElectronic works on other objects",() => { - expect(isElectronic({language:"javascript", typing:"dynamic"})).toBe(false); - expect(isElectronic(new ClassForTesting(42, "ElectronicDevice"))).toBe(false); - expect(isElectronic([1,2,3,4])).toBe(false) - }); - test("isElectronic works on non-objects",() => { - expect(isElectronic(true)).toBe(false) - expect(isElectronic(1234)).toBe(false) - expect(isElectronic(undefined)).toBe(false) - expect(isElectronic("Hello!")).toBe(false) - expect(isElectronic(Symbol("\u0070"))).toBe(false) - }); - test("a really long prototype chain",()=>{ - expect(isElectronic(new HomeMadePersonalComputer())).toBe(true) - }); -}); -describe("isNonEmptyArray", () => { - test("isNonEmptyArray works on non-empty arrays", () => { - expect(isNonEmptyArray([1, 2, 3])).toBe(true); - expect(isNonEmptyArray(['a', 'b'])).toBe(true); - }); - test("isNonEmptyArray works on empty arrays", () => { - expect(isNonEmptyArray([])).toBe(false); - }); - test("isNonEmptyArray works on non-arrays", () => { - expect(isNonEmptyArray({})).toBe(false); - expect(isNonEmptyArray("string")).toBe(false); - expect(isNonEmptyArray(123)).toBe(false); - }); -}); - -describe("isEmptyArray", () => { - test("isEmptyArray works on empty arrays", () => { - expect(isEmptyArray([])).toBe(true); - }); - test("isEmptyArray works on non-empty arrays", () => { - expect(isEmptyArray([1, 2, 3])).toBe(false); - }); - test("isEmptyArray works on non-arrays", () => { - expect(isEmptyArray({})).toBe(false); - expect(isEmptyArray("string")).toBe(false); - expect(isEmptyArray(123)).toBe(false); - }); -}); -class TestAssertHasId { - id(){} -} -describe("assertHasId", () => { - test("assertHasId throws error if object has no 'id' property or method", () => { - expect(() => assertHasId({})).toThrow(); - }); - test("assertHasId does not throw error if object has 'id' property or method", () => { - expect(() => assertHasId({ id: 1 })).not.toThrow(); - expect(() => assertHasId(new TestAssertHasId())).not.toThrow(); - }); -}); -class TestHasType { - type(){} -} -describe("hasType", () => { - test("hasType works correctly", () => { - expect(hasType({ type: 'example' })).toBe(true); - expect(hasType({})).toBe(false); - expect(hasType(new TestHasType())).toBe(true) - }); -}); - -describe("hasIdProperty", () => { - test("hasIdProperty works correctly", () => { - expect(hasIdProperty({ id: 'test' })).toBe(true); - expect(hasIdProperty({})).toBe(false); - expect(hasIdProperty(new ClassForTesting())).toBe(false); - - }); -}); - -describe("hasDefinedType", () => { - test("hasDefinedType works correctly", () => { - expect(hasDefinedType({ type: 'example' })).toBe(true); - expect(hasDefinedType({ type: undefined })).toBe(false); - expect(hasDefinedType({})).toBe(false); - }); -}); +import { describe, expect, test } from '@jest/globals'; +import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasIdProperty, hasDefinedType} from './assembly-line' +describe("isBoolean",() => { + test("isBoolean works on booleans",() => { + expect(isBoolean(true)).toBe(true) + expect(isBoolean(false)).toBe(true) + }); + test("isBoolean works on non-booleans",() => { + expect(isBoolean(42)).toBe(false) + expect(isBoolean("Hello, World!")).toBe(false) + expect(isBoolean(null)).toBe(false) + expect(isBoolean("")).toBe(false) + expect(isBoolean(Symbol("1"))).toBe(false) + }); +}); +describe("isNumber",() => { + test("isNumber works on numbers",() => { + expect(isNumber(42)).toBe(true); + expect(isNumber(92)).toBe(true); + expect(isNumber(43859435.12)).toBe(true); + }); + test("isNumber works on bigints",() => { + expect(isNumber(42n)).toBe(true); + expect(isNumber(92n)).toBe(true); + expect(isNumber(1848958451n)).toBe(true) + }); + test("isNumber works on non-numbers",() => { + expect(isNumber(true)).toBe(false) + expect(isNumber("Hello, World!")).toBe(false) + expect(isNumber(null)).toBe(false) + expect(isNumber("")).toBe(false) + expect(isNumber(Symbol("1"))).toBe(false) + }); + test("isNumber works on NaN and Infinity",() => { + expect(isNumber(NaN)).toBe(false) + expect(isNumber(Infinity)).toBe(false) + }) +}); +class ClassForTesting { + constructor(number,word){ + this.number = number; + this.word = word; + } + id(){} +} +describe("isObject",() => { + test("isObject works on objects",() => { + expect(isObject({})).toBe(true); + expect(isObject({greeting:"hello"})).toBe(true); + }); + test("isObject works on class instances",() => { + expect(isObject(new ClassForTesting(5,"Hello"))).toBe(true); + expect(isObject(new ClassForTesting(58,"null"))).toBe(true); + expect(isObject(new ClassForTesting(1488,"World!"))).toBe(true) + }); + test("isObject works on non-Objects",() => { + expect(isObject(true)).toBe(false) + expect(isObject("Hello, World!")).toBe(false) + expect(isObject(undefined)).toBe(false) + expect(isObject("")).toBe(false) + expect(isObject(Symbol("1"))).toBe(false) + }); + test("isObject works on null",() => { + expect(isObject(null)).toBe(false) + }) +}); +describe("isNumericString",() => { + test("isNumericString works on numeric strings",() => { + expect(isNumericString("42")).toBe(true); + expect(isNumericString("582")).toBe(true); + }); + test("isNumericString works on non-numeric strings",() => { + expect(isNumericString("Hello, World!")).toBe(false); + expect(isNumericString("")).toBe(false); + expect(isNumericString("NaN")).toBe(false) + }); + test("isNumericString works on non-strings",() => { + expect(isNumericString(true)).toBe(false) + expect(isNumericString(1234)).toBe(false) + expect(isNumericString(undefined)).toBe(false) + expect(isNumericString([1,2,3,4])).toBe(false) + expect(isNumericString(Symbol("\u0070"))).toBe(false) + }); +}); +class Oven extends ElectronicDevice {} +class Computer extends ElectronicDevice {} +class PersonalComputer extends Computer {} +class HomeMadePersonalComputer extends PersonalComputer {} +describe("isElectronic",() => { + test("isElectronic works on instances of ElectronicDevice or its child classes",() => { + expect(isElectronic(new ElectronicDevice())).toBe(true); + expect(isElectronic(new Oven())).toBe(true); + }); + test("isElectronic works on other objects",() => { + expect(isElectronic({language:"javascript", typing:"dynamic"})).toBe(false); + expect(isElectronic(new ClassForTesting(42, "ElectronicDevice"))).toBe(false); + expect(isElectronic([1,2,3,4])).toBe(false) + }); + test("isElectronic works on non-objects",() => { + expect(isElectronic(true)).toBe(false) + expect(isElectronic(1234)).toBe(false) + expect(isElectronic(undefined)).toBe(false) + expect(isElectronic("Hello!")).toBe(false) + expect(isElectronic(Symbol("\u0070"))).toBe(false) + }); + test("a really long prototype chain",()=>{ + expect(isElectronic(new HomeMadePersonalComputer())).toBe(true) + }); +}); +describe("isNonEmptyArray", () => { + test("isNonEmptyArray works on non-empty arrays", () => { + expect(isNonEmptyArray([1, 2, 3])).toBe(true); + expect(isNonEmptyArray(['a', 'b'])).toBe(true); + }); + test("isNonEmptyArray works on empty arrays", () => { + expect(isNonEmptyArray([])).toBe(false); + }); + test("isNonEmptyArray works on non-arrays", () => { + expect(isNonEmptyArray({})).toBe(false); + expect(isNonEmptyArray("string")).toBe(false); + expect(isNonEmptyArray(123)).toBe(false); + }); +}); + +describe("isEmptyArray", () => { + test("isEmptyArray works on empty arrays", () => { + expect(isEmptyArray([])).toBe(true); + }); + test("isEmptyArray works on non-empty arrays", () => { + expect(isEmptyArray([1, 2, 3])).toBe(false); + }); + test("isEmptyArray works on non-arrays", () => { + expect(isEmptyArray({})).toBe(false); + expect(isEmptyArray("string")).toBe(false); + expect(isEmptyArray(123)).toBe(false); + }); +}); +class TestAssertHasId { + id(){} +} +describe("assertHasId", () => { + test("assertHasId throws error if object has no 'id' property or method", () => { + expect(() => assertHasId({})).toThrow(); + }); + test("assertHasId does not throw error if object has 'id' property or method", () => { + expect(() => assertHasId({ id: 1 })).not.toThrow(); + expect(() => assertHasId(new TestAssertHasId())).not.toThrow(); + }); +}); +class TestHasType { + type(){} +} +describe("hasType", () => { + test("hasType works correctly", () => { + expect(hasType({ type: 'example' })).toBe(true); + expect(hasType({})).toBe(false); + expect(hasType(new TestHasType())).toBe(true) + }); +}); + +describe("hasIdProperty", () => { + test("hasIdProperty works correctly", () => { + expect(hasIdProperty({ id: 'test' })).toBe(true); + expect(hasIdProperty({})).toBe(false); + expect(hasIdProperty(new ClassForTesting())).toBe(false); + + }); +}); + +describe("hasDefinedType", () => { + test("hasDefinedType works correctly", () => { + expect(hasDefinedType({ type: 'example' })).toBe(true); + expect(hasDefinedType({ type: undefined })).toBe(false); + expect(hasDefinedType({})).toBe(false); + }); +}); diff --git a/exercises/concept/assembly-line/babel.config.js b/exercises/concept/recycling-robot/babel.config.js similarity index 100% rename from exercises/concept/assembly-line/babel.config.js rename to exercises/concept/recycling-robot/babel.config.js diff --git a/exercises/concept/assembly-line/eslint.config.mjs b/exercises/concept/recycling-robot/eslint.config.mjs similarity index 100% rename from exercises/concept/assembly-line/eslint.config.mjs rename to exercises/concept/recycling-robot/eslint.config.mjs diff --git a/exercises/concept/assembly-line/jest.config.js b/exercises/concept/recycling-robot/jest.config.js similarity index 100% rename from exercises/concept/assembly-line/jest.config.js rename to exercises/concept/recycling-robot/jest.config.js diff --git a/exercises/concept/assembly-line/package.json b/exercises/concept/recycling-robot/package.json similarity index 100% rename from exercises/concept/assembly-line/package.json rename to exercises/concept/recycling-robot/package.json From d6631bf2f642204f70f4bfbfacc844f7cfed2df0 Mon Sep 17 00:00:00 2001 From: J R M Date: Tue, 1 Jul 2025 11:08:06 +0200 Subject: [PATCH 086/146] Fix typo in instructions.md --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index e793c14a6a..49f725c0c7 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -146,7 +146,7 @@ hasType(new Keyboard()) ### 10. Check if an object has an `id` property -Implement the `hasIdProperty` function, that checks whether an object has a `constructor` property. +Implement the `hasIdProperty` function, that checks whether an object has an `id` property. ```javascript class MyClass { From 326bbdbde165278f555f1be66b31a0f318a75f48 Mon Sep 17 00:00:00 2001 From: J R M Date: Tue, 1 Jul 2025 11:11:52 +0200 Subject: [PATCH 087/146] Update hints.md Some hints were outdated. --- exercises/concept/recycling-robot/.docs/hints.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/concept/recycling-robot/.docs/hints.md b/exercises/concept/recycling-robot/.docs/hints.md index 46f5dcd175..f57432aa67 100644 --- a/exercises/concept/recycling-robot/.docs/hints.md +++ b/exercises/concept/recycling-robot/.docs/hints.md @@ -41,22 +41,22 @@ - `typeof` returns a string. - You can check the length of an array to find out how many elements it contains. -## 8. Throw an error if an object does not have the `id` property +## 8. Throw an error if an object does not have the `id` property or method -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. -- If the `id` property is missing, your function should throw an `Error`. +- You can use the `in` operator to check if an object has a property or method. +- If the `id` property or method is missing, your function should throw an `Error`. -## 9. Check if an object has a `type` property +## 9. Check if an object has a `type` property or method -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- You can use the `in` operator to check if an object has a property or method. -## 10. Check if an object has a `constructor` property +## 10. Check if an object has an `id` property -- All class instances have a `constructor`, but `Object.hasOwn()` is able to ignore this. +- To check if an object has a property (not a method), you can use the `Object.hasOwn()` function. ## 11. Check if an object has a defined `type` property -- You can use the `in` operator or the `Object.hasOwn()` function to check if an object has a property. +- To check if an object has a property (not a method), you can use the `Object.hasOwn()` function. - You will have to access the `type` property and check if it is defined. [isNaN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN From 511e5a0db383529cb4aa8074d261db3d44de8199 Mon Sep 17 00:00:00 2001 From: J R M Date: Tue, 1 Jul 2025 09:18:49 +0200 Subject: [PATCH 088/146] Format --- concepts/type-checking/about.md | 12 +- concepts/type-checking/introduction.md | 12 +- .../concept/recycling-robot/.docs/hints.md | 1 - .../recycling-robot/.docs/instructions.md | 66 +++--- .../recycling-robot/.docs/introduction.md | 12 +- .../concept/recycling-robot/.meta/exemplar.js | 35 +-- .../concept/recycling-robot/assembly-line.js | 28 ++- .../recycling-robot/assembly-line.spec.js | 220 ++++++++++-------- 8 files changed, 211 insertions(+), 175 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index df5e4d5ce9..c3a4bd11d3 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -3,11 +3,13 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. -~~~~exercism/note + +```exercism/note Javascript's type checking mechanisms are always soomewhat unreliable. For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. -~~~~ +``` + ## The `typeof` operator The `typeof` operator returns the type of its input. @@ -127,13 +129,13 @@ class Coffee { } const cappuccino = new Coffee(); -Object.hasOwn(cappucino,'temperature'); +Object.hasOwn(cappucino, 'temperature'); // => true -Object.hasOwn(cappucino,'constructor'); +Object.hasOwn(cappucino, 'constructor'); // => false -Object.hasOwn(cappucino,'coolDown'); +Object.hasOwn(cappucino, 'coolDown'); // => false ``` diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index df5e4d5ce9..c3a4bd11d3 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -3,11 +3,13 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. -~~~~exercism/note + +```exercism/note Javascript's type checking mechanisms are always soomewhat unreliable. For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. -~~~~ +``` + ## The `typeof` operator The `typeof` operator returns the type of its input. @@ -127,13 +129,13 @@ class Coffee { } const cappuccino = new Coffee(); -Object.hasOwn(cappucino,'temperature'); +Object.hasOwn(cappucino, 'temperature'); // => true -Object.hasOwn(cappucino,'constructor'); +Object.hasOwn(cappucino, 'constructor'); // => false -Object.hasOwn(cappucino,'coolDown'); +Object.hasOwn(cappucino, 'coolDown'); // => false ``` diff --git a/exercises/concept/recycling-robot/.docs/hints.md b/exercises/concept/recycling-robot/.docs/hints.md index f57432aa67..ebf8921f38 100644 --- a/exercises/concept/recycling-robot/.docs/hints.md +++ b/exercises/concept/recycling-robot/.docs/hints.md @@ -1,6 +1,5 @@ # Hints - ## 1. Check if a value is a boolean - You can use `typeof` to find the type of a value. diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 49f725c0c7..4782962262 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -4,19 +4,20 @@ You have been hired by a recycling center. Due to lack of space, all the products are put on the same conveyor belt, but this has lead to different materials mixing together, making them unusable. To fix this, you have been tasked with making functions to identify the type of a product. -~~~~exercism/note +```exercism/note Many of the later tasks in this exercise can be solved using either `in` or `Object.hasOwn()`. To practice, try to solve them with a mix of both. -~~~~ +``` + ### 1. Check if a value is a boolean Implement the `isBoolean` function, that checks if a value is a boolean. ```javascript -isBoolean(true) +isBoolean(true); // => true -isBoolean(null) +isBoolean(null); // => false ``` @@ -28,16 +29,16 @@ Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN Your function should be able to correctly handle this as well. ```javascript -isNumber(42) +isNumber(42); // => true -isNumber("Hello, World!") +isNumber('Hello, World!'); // => false -isNumber(42n) +isNumber(42n); // => true -isNumber(NaN) +isNumber(NaN); // => false ``` @@ -46,10 +47,10 @@ isNumber(NaN) Implement the `isObject` function, that should check if the value is actually an object, not null. ```javascript -isObject({greeting:"Hello"}) +isObject({ greeting: 'Hello' }); // => true -isObject(25n) +isObject(25n); // => false ``` @@ -58,15 +59,14 @@ isObject(25n) Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. ```javascript -isNumericString(42) +isNumericString(42); // => false -isNumericString("42") +isNumericString('42'); // => true -isNumericString("Hi!") +isNumericString('Hi!'); // => false - ``` ### 5. Check if an object is electronic @@ -80,10 +80,10 @@ class Duck { class WashingMachine extends ElectronicDevice { //... } -isElectronic(new Duck()) +isElectronic(new Duck()); // => false -isElectronic(new WashingMachine()) +isElectronic(new WashingMachine()); // => false ``` @@ -92,21 +92,22 @@ isElectronic(new WashingMachine()) Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. ```javascript -isNonEmptyArray([1,2,3]) +isNonEmptyArray([1, 2, 3]); // => true -isNonEmptyArray([]) +isNonEmptyArray([]); // => false ``` ### 7. Check if a value is an empty array Implement the `isEmptyArray` function, that checks if an object is an empty array. + ```javascript -isEmptyArray([1,2,3]) +isEmptyArray([1, 2, 3]); // => false -isEmptyArray([]) +isEmptyArray([]); // => true ``` @@ -117,10 +118,10 @@ Implement the `assertHasId` function, that will throw an `Error` if an object is If an object does have the `id` property, it should not return anything. ```javascript -assertHasId({id:42,color:"red"}) +assertHasId({ id: 42, color: 'red' }); // => undefined -assertHasId({color:"green"}) +assertHasId({ color: 'green' }); // Error: "Object is missing the 'id' property" ``` @@ -151,33 +152,34 @@ Implement the `hasIdProperty` function, that checks whether an object has an `id ```javascript class MyClass { constructor() { - this.number = "42" - this.id = "BC269327FE1D9B95" + this.number = '42'; + this.id = 'BC269327FE1D9B95'; } } class MyNewClass { constructor() { - this.number = "42" - this._id = "BC269327FE1D9B95" + this.number = '42'; + this._id = 'BC269327FE1D9B95'; } - get id(){ - return this._id + get id() { + return this._id; } } -hasIdProperty(new MyClass()) +hasIdProperty(new MyClass()); // => true -hasIdProperty(new MyNewClass()) +hasIdProperty(new MyNewClass()); // => false ``` + ### 11. Check if an object has a defined `type` property Implement the `hasDefinedType` function, that checks if an object has a `type` property that is not `undefined`. ```javascript -hasDefinedType({type:undefined,color:"red"}) +hasDefinedType({ type: undefined, color: 'red' }); // => false -hasDefinedType({type:"car",color:"green"}) +hasDefinedType({ type: 'car', color: 'green' }); // => true ``` diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index df5e4d5ce9..c3a4bd11d3 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -3,11 +3,13 @@ Knowning what type an object has is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. -~~~~exercism/note + +```exercism/note Javascript's type checking mechanisms are always soomewhat unreliable. For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. -~~~~ +``` + ## The `typeof` operator The `typeof` operator returns the type of its input. @@ -127,13 +129,13 @@ class Coffee { } const cappuccino = new Coffee(); -Object.hasOwn(cappucino,'temperature'); +Object.hasOwn(cappucino, 'temperature'); // => true -Object.hasOwn(cappucino,'constructor'); +Object.hasOwn(cappucino, 'constructor'); // => false -Object.hasOwn(cappucino,'coolDown'); +Object.hasOwn(cappucino, 'coolDown'); // => false ``` diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 791a20bd24..cacde0f80a 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -6,7 +6,7 @@ export class ElectronicDevice { // This class will be used in the exercise. -} +} /** * Checks if input is a boolean. * @@ -14,7 +14,7 @@ export class ElectronicDevice { * @returns {boolean} whether the input is a boolean */ export function isBoolean(value) { - return typeof value === "boolean" + return typeof value === 'boolean'; } /** @@ -24,7 +24,11 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - return (typeof value === "number"||typeof value === "bigint") && !isNaN(Number(value)) && value !== Infinity + return ( + (typeof value === 'number' || typeof value === 'bigint') && + !isNaN(Number(value)) && + value !== Infinity + ); } /** @@ -34,7 +38,7 @@ export function isNumber(value) { * @returns {boolean} whether the input is an object. */ export function isObject(value) { - return value !== null && typeof value === "object" + return value !== null && typeof value === 'object'; } /** @@ -44,7 +48,12 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - return typeof value === "string" && value.split("").every((char) => {return /[0-9]/.test(char)}) + return ( + typeof value === 'string' && + value.split('').every((char) => { + return /[0-9]/.test(char); + }) + ); } /** @@ -54,7 +63,7 @@ export function isNumericString(value) { * @returns {boolean} whether the object is an instance of the "ElectronicDevice" class or one of its children. */ export function isElectronic(object) { - return object instanceof ElectronicDevice + return object instanceof ElectronicDevice; } /** @@ -64,7 +73,7 @@ export function isElectronic(object) { * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { - return value instanceof Array && value.length > 0 + return value instanceof Array && value.length > 0; } /** @@ -74,7 +83,7 @@ export function isNonEmptyArray(value) { * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { - return value instanceof Array && value.length === 0 + return value instanceof Array && value.length === 0; } /** @@ -84,10 +93,10 @@ export function isEmptyArray(value) { * @returns {boolean} undefined if the input has an "id" property, otherwise throws an error. */ export function assertHasId(object) { - if ("id" in object){ + if ('id' in object) { return; } - throw new Error('The "id" property is missing.') + throw new Error('The "id" property is missing.'); } /** @@ -97,7 +106,7 @@ export function assertHasId(object) { * @returns {boolean} whether the input has a "type" property. */ export function hasType(object) { - return "type" in object + return 'type' in object; } /** @@ -107,7 +116,7 @@ export function hasType(object) { * @returns {boolean} whether the input has a "id" property. */ export function hasIdProperty(object) { - return Object.hasOwn(object,"id") + return Object.hasOwn(object, 'id'); } /** @@ -117,5 +126,5 @@ export function hasIdProperty(object) { * @returns {boolean} whether the input has a defined "type" property. */ export function hasDefinedType(object) { - return Object.hasOwn(object, "type") && object.type !== undefined + return Object.hasOwn(object, 'type') && object.type !== undefined; } diff --git a/exercises/concept/recycling-robot/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js index 794e298b2d..c12edca3c8 100644 --- a/exercises/concept/recycling-robot/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -6,7 +6,7 @@ export class ElectronicDevice { // This class will be used in the exercise. -} +} /** * Checks if input is a boolean. * @@ -14,7 +14,7 @@ export class ElectronicDevice { * @returns {boolean} whether the input is a boolean */ export function isBoolean(value) { - throw new Error("Remove this line and implement the isBoolean function") + throw new Error('Remove this line and implement the isBoolean function'); } /** @@ -24,7 +24,7 @@ export function isBoolean(value) { * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { - throw new Error("Remove this line and implement the isNumber function") + throw new Error('Remove this line and implement the isNumber function'); } /** @@ -34,7 +34,7 @@ export function isNumber(value) { * @returns {boolean} whether the input is an object. */ export function isObject(value) { - throw new Error("Remove this line and implement the isObject function") + throw new Error('Remove this line and implement the isObject function'); } /** @@ -44,7 +44,9 @@ export function isObject(value) { * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { - throw new Error("Remove this line and implement the isNumericString function") + throw new Error( + 'Remove this line and implement the isNumericString function', + ); } /** @@ -54,7 +56,7 @@ export function isNumericString(value) { * @returns {boolean} whether the object is an instance of the `ElectronicDevice` class or one of its children. */ export function isElectronic(object) { - throw new Error("Remove this line and implement the isElectronic function") + throw new Error('Remove this line and implement the isElectronic function'); } /** @@ -64,7 +66,9 @@ export function isElectronic(object) { * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { - throw new Error("Remove this line and implement the isNonEmptyArray function") + throw new Error( + 'Remove this line and implement the isNonEmptyArray function', + ); } /** @@ -74,7 +78,7 @@ export function isNonEmptyArray(value) { * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { - throw new Error("Remove this line and implement the isEmptyArray function") + throw new Error('Remove this line and implement the isEmptyArray function'); } /** @@ -84,7 +88,7 @@ export function isEmptyArray(value) { * @returns {undefined} undefined if the input has an "id" property or method, otherwise throws an error. */ export function assertHasId(object) { - throw new Error("Remove this line and implement the assertHasId function") + throw new Error('Remove this line and implement the assertHasId function'); } /** @@ -94,7 +98,7 @@ export function assertHasId(object) { * @returns {boolean} whether the input has a "type" property or method. */ export function hasType(object) { - throw new Error("Remove this line and implement the hasType function") + throw new Error('Remove this line and implement the hasType function'); } /** @@ -104,7 +108,7 @@ export function hasType(object) { * @returns {boolean} whether the input has an "id" property. */ export function hasIdProperty(object) { - throw new Error("Remove this line and implement the hasIdProperty function") + throw new Error('Remove this line and implement the hasIdProperty function'); } /** @@ -114,5 +118,5 @@ export function hasIdProperty(object) { * @returns {boolean} whether the input has a defined "type" property. */ export function hasDefinedType(object) { - throw new Error("Remove this line and implement the hasDefinedType function") + throw new Error('Remove this line and implement the hasDefinedType function'); } diff --git a/exercises/concept/recycling-robot/assembly-line.spec.js b/exercises/concept/recycling-robot/assembly-line.spec.js index 8a8d097208..b470bdfe8a 100644 --- a/exercises/concept/recycling-robot/assembly-line.spec.js +++ b/exercises/concept/recycling-robot/assembly-line.spec.js @@ -1,144 +1,161 @@ import { describe, expect, test } from '@jest/globals'; -import { isBoolean, isNumber, isObject, isNumericString, ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray , assertHasId, hasType, hasIdProperty, hasDefinedType} from './assembly-line' -describe("isBoolean",() => { - test("isBoolean works on booleans",() => { - expect(isBoolean(true)).toBe(true) - expect(isBoolean(false)).toBe(true) - }); - test("isBoolean works on non-booleans",() => { - expect(isBoolean(42)).toBe(false) - expect(isBoolean("Hello, World!")).toBe(false) - expect(isBoolean(null)).toBe(false) - expect(isBoolean("")).toBe(false) - expect(isBoolean(Symbol("1"))).toBe(false) +import { + isBoolean, + isNumber, + isObject, + isNumericString, + ElectronicDevice, + isElectronic, + isNonEmptyArray, + isEmptyArray, + assertHasId, + hasType, + hasIdProperty, + hasDefinedType, +} from './assembly-line'; +describe('isBoolean', () => { + test('isBoolean works on booleans', () => { + expect(isBoolean(true)).toBe(true); + expect(isBoolean(false)).toBe(true); + }); + test('isBoolean works on non-booleans', () => { + expect(isBoolean(42)).toBe(false); + expect(isBoolean('Hello, World!')).toBe(false); + expect(isBoolean(null)).toBe(false); + expect(isBoolean('')).toBe(false); + expect(isBoolean(Symbol('1'))).toBe(false); }); }); -describe("isNumber",() => { - test("isNumber works on numbers",() => { +describe('isNumber', () => { + test('isNumber works on numbers', () => { expect(isNumber(42)).toBe(true); expect(isNumber(92)).toBe(true); expect(isNumber(43859435.12)).toBe(true); }); - test("isNumber works on bigints",() => { + test('isNumber works on bigints', () => { expect(isNumber(42n)).toBe(true); expect(isNumber(92n)).toBe(true); - expect(isNumber(1848958451n)).toBe(true) - }); - test("isNumber works on non-numbers",() => { - expect(isNumber(true)).toBe(false) - expect(isNumber("Hello, World!")).toBe(false) - expect(isNumber(null)).toBe(false) - expect(isNumber("")).toBe(false) - expect(isNumber(Symbol("1"))).toBe(false) - }); - test("isNumber works on NaN and Infinity",() => { - expect(isNumber(NaN)).toBe(false) - expect(isNumber(Infinity)).toBe(false) - }) + expect(isNumber(1848958451n)).toBe(true); + }); + test('isNumber works on non-numbers', () => { + expect(isNumber(true)).toBe(false); + expect(isNumber('Hello, World!')).toBe(false); + expect(isNumber(null)).toBe(false); + expect(isNumber('')).toBe(false); + expect(isNumber(Symbol('1'))).toBe(false); + }); + test('isNumber works on NaN and Infinity', () => { + expect(isNumber(NaN)).toBe(false); + expect(isNumber(Infinity)).toBe(false); + }); }); class ClassForTesting { - constructor(number,word){ + constructor(number, word) { this.number = number; this.word = word; } - id(){} + id() {} } -describe("isObject",() => { - test("isObject works on objects",() => { +describe('isObject', () => { + test('isObject works on objects', () => { expect(isObject({})).toBe(true); - expect(isObject({greeting:"hello"})).toBe(true); - }); - test("isObject works on class instances",() => { - expect(isObject(new ClassForTesting(5,"Hello"))).toBe(true); - expect(isObject(new ClassForTesting(58,"null"))).toBe(true); - expect(isObject(new ClassForTesting(1488,"World!"))).toBe(true) - }); - test("isObject works on non-Objects",() => { - expect(isObject(true)).toBe(false) - expect(isObject("Hello, World!")).toBe(false) - expect(isObject(undefined)).toBe(false) - expect(isObject("")).toBe(false) - expect(isObject(Symbol("1"))).toBe(false) - }); - test("isObject works on null",() => { - expect(isObject(null)).toBe(false) - }) + expect(isObject({ greeting: 'hello' })).toBe(true); + }); + test('isObject works on class instances', () => { + expect(isObject(new ClassForTesting(5, 'Hello'))).toBe(true); + expect(isObject(new ClassForTesting(58, 'null'))).toBe(true); + expect(isObject(new ClassForTesting(1488, 'World!'))).toBe(true); + }); + test('isObject works on non-Objects', () => { + expect(isObject(true)).toBe(false); + expect(isObject('Hello, World!')).toBe(false); + expect(isObject(undefined)).toBe(false); + expect(isObject('')).toBe(false); + expect(isObject(Symbol('1'))).toBe(false); + }); + test('isObject works on null', () => { + expect(isObject(null)).toBe(false); + }); }); -describe("isNumericString",() => { - test("isNumericString works on numeric strings",() => { - expect(isNumericString("42")).toBe(true); - expect(isNumericString("582")).toBe(true); - }); - test("isNumericString works on non-numeric strings",() => { - expect(isNumericString("Hello, World!")).toBe(false); - expect(isNumericString("")).toBe(false); - expect(isNumericString("NaN")).toBe(false) - }); - test("isNumericString works on non-strings",() => { - expect(isNumericString(true)).toBe(false) - expect(isNumericString(1234)).toBe(false) - expect(isNumericString(undefined)).toBe(false) - expect(isNumericString([1,2,3,4])).toBe(false) - expect(isNumericString(Symbol("\u0070"))).toBe(false) +describe('isNumericString', () => { + test('isNumericString works on numeric strings', () => { + expect(isNumericString('42')).toBe(true); + expect(isNumericString('582')).toBe(true); + }); + test('isNumericString works on non-numeric strings', () => { + expect(isNumericString('Hello, World!')).toBe(false); + expect(isNumericString('')).toBe(false); + expect(isNumericString('NaN')).toBe(false); + }); + test('isNumericString works on non-strings', () => { + expect(isNumericString(true)).toBe(false); + expect(isNumericString(1234)).toBe(false); + expect(isNumericString(undefined)).toBe(false); + expect(isNumericString([1, 2, 3, 4])).toBe(false); + expect(isNumericString(Symbol('\u0070'))).toBe(false); }); }); class Oven extends ElectronicDevice {} class Computer extends ElectronicDevice {} class PersonalComputer extends Computer {} class HomeMadePersonalComputer extends PersonalComputer {} -describe("isElectronic",() => { - test("isElectronic works on instances of ElectronicDevice or its child classes",() => { +describe('isElectronic', () => { + test('isElectronic works on instances of ElectronicDevice or its child classes', () => { expect(isElectronic(new ElectronicDevice())).toBe(true); expect(isElectronic(new Oven())).toBe(true); }); - test("isElectronic works on other objects",() => { - expect(isElectronic({language:"javascript", typing:"dynamic"})).toBe(false); - expect(isElectronic(new ClassForTesting(42, "ElectronicDevice"))).toBe(false); - expect(isElectronic([1,2,3,4])).toBe(false) - }); - test("isElectronic works on non-objects",() => { - expect(isElectronic(true)).toBe(false) - expect(isElectronic(1234)).toBe(false) - expect(isElectronic(undefined)).toBe(false) - expect(isElectronic("Hello!")).toBe(false) - expect(isElectronic(Symbol("\u0070"))).toBe(false) - }); - test("a really long prototype chain",()=>{ - expect(isElectronic(new HomeMadePersonalComputer())).toBe(true) + test('isElectronic works on other objects', () => { + expect(isElectronic({ language: 'javascript', typing: 'dynamic' })).toBe( + false, + ); + expect(isElectronic(new ClassForTesting(42, 'ElectronicDevice'))).toBe( + false, + ); + expect(isElectronic([1, 2, 3, 4])).toBe(false); + }); + test('isElectronic works on non-objects', () => { + expect(isElectronic(true)).toBe(false); + expect(isElectronic(1234)).toBe(false); + expect(isElectronic(undefined)).toBe(false); + expect(isElectronic('Hello!')).toBe(false); + expect(isElectronic(Symbol('\u0070'))).toBe(false); + }); + test('a really long prototype chain', () => { + expect(isElectronic(new HomeMadePersonalComputer())).toBe(true); }); }); -describe("isNonEmptyArray", () => { - test("isNonEmptyArray works on non-empty arrays", () => { +describe('isNonEmptyArray', () => { + test('isNonEmptyArray works on non-empty arrays', () => { expect(isNonEmptyArray([1, 2, 3])).toBe(true); expect(isNonEmptyArray(['a', 'b'])).toBe(true); }); - test("isNonEmptyArray works on empty arrays", () => { + test('isNonEmptyArray works on empty arrays', () => { expect(isNonEmptyArray([])).toBe(false); }); - test("isNonEmptyArray works on non-arrays", () => { + test('isNonEmptyArray works on non-arrays', () => { expect(isNonEmptyArray({})).toBe(false); - expect(isNonEmptyArray("string")).toBe(false); + expect(isNonEmptyArray('string')).toBe(false); expect(isNonEmptyArray(123)).toBe(false); }); }); -describe("isEmptyArray", () => { - test("isEmptyArray works on empty arrays", () => { +describe('isEmptyArray', () => { + test('isEmptyArray works on empty arrays', () => { expect(isEmptyArray([])).toBe(true); }); - test("isEmptyArray works on non-empty arrays", () => { + test('isEmptyArray works on non-empty arrays', () => { expect(isEmptyArray([1, 2, 3])).toBe(false); }); - test("isEmptyArray works on non-arrays", () => { + test('isEmptyArray works on non-arrays', () => { expect(isEmptyArray({})).toBe(false); - expect(isEmptyArray("string")).toBe(false); + expect(isEmptyArray('string')).toBe(false); expect(isEmptyArray(123)).toBe(false); }); }); class TestAssertHasId { - id(){} + id() {} } -describe("assertHasId", () => { +describe('assertHasId', () => { test("assertHasId throws error if object has no 'id' property or method", () => { expect(() => assertHasId({})).toThrow(); }); @@ -148,27 +165,26 @@ describe("assertHasId", () => { }); }); class TestHasType { - type(){} + type() {} } -describe("hasType", () => { - test("hasType works correctly", () => { +describe('hasType', () => { + test('hasType works correctly', () => { expect(hasType({ type: 'example' })).toBe(true); expect(hasType({})).toBe(false); - expect(hasType(new TestHasType())).toBe(true) + expect(hasType(new TestHasType())).toBe(true); }); }); -describe("hasIdProperty", () => { - test("hasIdProperty works correctly", () => { +describe('hasIdProperty', () => { + test('hasIdProperty works correctly', () => { expect(hasIdProperty({ id: 'test' })).toBe(true); expect(hasIdProperty({})).toBe(false); expect(hasIdProperty(new ClassForTesting())).toBe(false); - }); }); -describe("hasDefinedType", () => { - test("hasDefinedType works correctly", () => { +describe('hasDefinedType', () => { + test('hasDefinedType works correctly', () => { expect(hasDefinedType({ type: 'example' })).toBe(true); expect(hasDefinedType({ type: undefined })).toBe(false); expect(hasDefinedType({})).toBe(false); From e8fb4e9c8ab7693cbb80597880dc33b1ae9c5265 Mon Sep 17 00:00:00 2001 From: J R M Date: Tue, 1 Jul 2025 11:26:09 +0200 Subject: [PATCH 089/146] Update instructions.md Removed now unnecessary note. --- exercises/concept/recycling-robot/.docs/instructions.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 4782962262..2bf013b563 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -4,10 +4,7 @@ You have been hired by a recycling center. Due to lack of space, all the products are put on the same conveyor belt, but this has lead to different materials mixing together, making them unusable. To fix this, you have been tasked with making functions to identify the type of a product. -```exercism/note -Many of the later tasks in this exercise can be solved using either `in` or `Object.hasOwn()`. -To practice, try to solve them with a mix of both. -``` + ### 1. Check if a value is a boolean From 2007b106bdc572e73f88b80eaa3f62fa4f0fa593 Mon Sep 17 00:00:00 2001 From: J R M Date: Tue, 1 Jul 2025 11:30:55 +0200 Subject: [PATCH 090/146] Update instructions.md --- exercises/concept/recycling-robot/.docs/instructions.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 2bf013b563..b863e655c4 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -4,8 +4,6 @@ You have been hired by a recycling center. Due to lack of space, all the products are put on the same conveyor belt, but this has lead to different materials mixing together, making them unusable. To fix this, you have been tasked with making functions to identify the type of a product. - - ### 1. Check if a value is a boolean Implement the `isBoolean` function, that checks if a value is a boolean. From 246ac06b88d0284b502b28577873070353fae966 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:29:03 +0200 Subject: [PATCH 091/146] Update concepts/type-checking/.meta/config.json Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/.meta/config.json b/concepts/type-checking/.meta/config.json index d50db081eb..f96e488604 100644 --- a/concepts/type-checking/.meta/config.json +++ b/concepts/type-checking/.meta/config.json @@ -1,5 +1,5 @@ { - "blurb": "Learn how to check the type of an object in JavaScript", + "blurb": "Learn how to check the type of a value or object in JavaScript", "authors": ["quintuple-mallard"], "contributors": [] } From fab8038200c7a4128e9b9d2b1d2ca0cea9dff9a8 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:29:17 +0200 Subject: [PATCH 092/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index c3a4bd11d3..f5cd4cde33 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -1,6 +1,6 @@ # About -Knowning what type an object has is often very important for code to run smoothly and without errors. +Knowning what the type of a piece of data is, is often very important for code to run smoothly and without errors. Javascript has several ways to check the type of an object. From d40bada03d61ec8a458c0ee1e9f21defd891f57d Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:29:35 +0200 Subject: [PATCH 093/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index f5cd4cde33..b6b00c1038 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -2,7 +2,7 @@ Knowning what the type of a piece of data is, is often very important for code to run smoothly and without errors. -Javascript has several ways to check the type of an object. +Javascript has several ways to check the type of a value or object. ```exercism/note Javascript's type checking mechanisms are always soomewhat unreliable. From 88486ec634aae7053dffa28c694a38503807e9ab Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:30:15 +0200 Subject: [PATCH 094/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index b6b00c1038..957468e87f 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -5,7 +5,7 @@ Knowning what the type of a piece of data is, is often very important for code t Javascript has several ways to check the type of a value or object. ```exercism/note -Javascript's type checking mechanisms are always soomewhat unreliable. +Javascript's type checking mechanisms can be somewhat unreliable. For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. ``` From a43d16b3ca36ea2fcf40ed675fdf364ab7dca105 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:31:53 +0200 Subject: [PATCH 095/146] Update about.md --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 957468e87f..9e0c515f34 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -7,7 +7,7 @@ Javascript has several ways to check the type of a value or object. ```exercism/note Javascript's type checking mechanisms can be somewhat unreliable. -For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. ``` ## The `typeof` operator From 76f09141b0a466f5d941e1f7949121761537575b Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:32:11 +0200 Subject: [PATCH 096/146] Update introduction.md --- concepts/type-checking/introduction.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index c3a4bd11d3..466cefaddb 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -5,10 +5,9 @@ Knowning what type an object has is often very important for code to run smoothl Javascript has several ways to check the type of an object. ```exercism/note -Javascript's type checking mechanisms are always soomewhat unreliable. +Javascript's type checking mechanisms can be somewhat unreliable. -For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. -``` +For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language.``` ## The `typeof` operator From ed35aa7988c1c3fba3e128809551646bcb8a7be6 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:32:39 +0200 Subject: [PATCH 097/146] Update introduction.md --- exercises/concept/recycling-robot/.docs/introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index c3a4bd11d3..60ca3779e6 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -5,9 +5,9 @@ Knowning what type an object has is often very important for code to run smoothl Javascript has several ways to check the type of an object. ```exercism/note -Javascript's type checking mechanisms are always soomewhat unreliable. +Javascript's type checking mechanisms can be somewhat unreliable. -For true safety with types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. ``` ## The `typeof` operator From 80110188e3dafffd39a80c655fa464b23de0608f Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:36:40 +0200 Subject: [PATCH 098/146] Format --- concepts/callbacks/about.md | 3 --- concepts/closures/about.md | 2 -- concepts/type-checking/introduction.md | 4 ++-- exercises/concept/amusement-park/.meta/design.md | 4 ---- exercises/concept/bird-watcher/.meta/design.md | 3 --- exercises/concept/high-score-board/.meta/design.md | 6 ------ exercises/concept/mixed-juices/.meta/design.md | 3 --- exercises/concept/ozans-playlist/.meta/design.md | 2 -- 8 files changed, 2 insertions(+), 25 deletions(-) diff --git a/concepts/callbacks/about.md b/concepts/callbacks/about.md index 64fca0040f..1899983a55 100644 --- a/concepts/callbacks/about.md +++ b/concepts/callbacks/about.md @@ -81,7 +81,6 @@ You see this pattern often when dealing with asynchronous functions to assist wi Common `Array` functions use callback functions to define their behaviour: - `Array.prototype.forEach`: - - Accepts a callback, which applies the callback to each element of an array. ```javascript @@ -92,7 +91,6 @@ Common `Array` functions use callback functions to define their behaviour: ``` - `Array.prototype.map` - - Accepts a callback, which applies the callback to each element of an array using the result to create a new array. ```javascript @@ -103,7 +101,6 @@ Common `Array` functions use callback functions to define their behaviour: ``` - `Array.prototype.reduce` - - Accepts a callback, which applies the callback to each element of an array, passing the result forward to the next invocation. ```javascript diff --git a/concepts/closures/about.md b/concepts/closures/about.md index 957cac692a..23cf280315 100644 --- a/concepts/closures/about.md +++ b/concepts/closures/about.md @@ -18,7 +18,6 @@ The name _closure_ is historically derived from [_λ-calculus_][wiki-lambda-calc ## Reasons to use closures in JavaScript 1. Data Privacy / Data Encapsulation - - Unlike other languages, in 2020, there was no way to specify _private_ variables. So closures can be used to effectively emulate _private_ variables (there was a proposal to introduce private variable notation, which might have become standard by the time you read this). ```javascript @@ -37,7 +36,6 @@ The name _closure_ is historically derived from [_λ-calculus_][wiki-lambda-calc ``` 2. Partial Application - - Functions may return functions, and when a returned function uses the argument of the function that created it, this is an example of using a closure to perform partial application. Sometimes this is called _currying_ a function. ```javascript diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index 466cefaddb..e36248750c 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -4,7 +4,7 @@ Knowning what type an object has is often very important for code to run smoothl Javascript has several ways to check the type of an object. -```exercism/note +````exercism/note Javascript's type checking mechanisms can be somewhat unreliable. For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language.``` @@ -37,7 +37,7 @@ typeof [1, 2, 3, 4]; typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" -``` +```` The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. diff --git a/exercises/concept/amusement-park/.meta/design.md b/exercises/concept/amusement-park/.meta/design.md index ed3827a633..d974fff324 100644 --- a/exercises/concept/amusement-park/.meta/design.md +++ b/exercises/concept/amusement-park/.meta/design.md @@ -32,26 +32,22 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] The comment types mentioned below only serve as a proposal. 1. `createVisitor` - - `actionable`: If the student used a helper variable, give feedback that the result can be returned directly. - `celebratory`: If the student used classes, celebrate but let them know it is not necessary throughout this exercise. - `informative`: If the student did not use the short-hand notation but wrote `name: name` etc instead, let them know how to shorten that. The solution should be accepted nevertheless. 2. `revokeTicket` - - `essential`: Check the ticketId field is not deleted and re-added. - `celebratory`: If they used a method on a visitor class, celebrate but let them know it is not necessary for this exercise. 3. `ticketStatus` - - `essential`: Using a type switch should be discouraged since it is confusing to read because of the `typeof null === 'object'` quirk. - `informative`: If the student did not use early returns, maybe let them know about this alternative. - `celebratory`: Congratulate if the student used a template string for the "sold" case - `celebratory`: Congratulate if the student used a `value` helper variable. 4. `simpleTicketStatus` - - `essential`: Check `??` was used and not an if-statement or something else. - `actionable`: If the student used a helper variable, give feedback that the result can be returned directly. diff --git a/exercises/concept/bird-watcher/.meta/design.md b/exercises/concept/bird-watcher/.meta/design.md index 554e26f2c7..1b297b64d0 100644 --- a/exercises/concept/bird-watcher/.meta/design.md +++ b/exercises/concept/bird-watcher/.meta/design.md @@ -36,19 +36,16 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] For all tasks check that the student actually used a for loop. 1. `totalBirdCount` - - Verify that the condition is written with `< x.length` instead of `<= y.length -1`. - Check whether a shorthand assignment `+=` was used to increase the sum (non-essential feedback). - Verify the total was properly initialized with `0` instead of e.g. `null` - Verify the increment operator was used in loop header step 2. `birdsInWeek` - - Verify a helper variable was used instead of duplicating the calculation in the initialization and condition of the loop - Other checks should be the same as for `totalBirdCount` 3. `fixBirdCountLog` - - Check whether a shorthand assignment `+=` was used to increase the loop counter (non-essential feedback) - Check whether the increment operator was used in the loop body diff --git a/exercises/concept/high-score-board/.meta/design.md b/exercises/concept/high-score-board/.meta/design.md index 45307215e9..9c425cb787 100644 --- a/exercises/concept/high-score-board/.meta/design.md +++ b/exercises/concept/high-score-board/.meta/design.md @@ -40,33 +40,27 @@ The Concepts this exercise unlocks are: This exercise could benefit from the following rules in the [analyzer][analyzer]: 1. `createScoreBoard` - - `essential`: Make sure no class, map etc. was created, there should be just an object. - `actionable`: If the student created an empty object first and then added the value, give feedback to include the entry in the object literal directly. - `actionable`: Check that the object was returned directly, no intermediate assignment to a variable necessary. 2. `addPlayer` - - `essential`: Check the assignment operator was used and no additional variables were declared. 3. `removePlayer` - - `essential`: Make sure `delete` was used and not set to undefined or null. - `actionable`: If there is additional code to check whether the key is present before deleting it, give feedback that this is not necessary. 4. `updateScore` - - `actionable`: If the student used a separate variable to calculate the new value first, tell them it is not necessary. - `actionable`: If the student did not use the shorthand assignment operator, tell them about it. If they used it already, give a `celebratory` comment. 5. `applyMondayBonus` - - `essential`: Check the student actually used `for...in`. - Same feedback as in `updateScore` applies. - Using `updateScore` in the solution should be treated as equally correct as the exemplar solution. 6. `normalizeScore` - - `actionable`: No intermediate variables necessary. ## Notes diff --git a/exercises/concept/mixed-juices/.meta/design.md b/exercises/concept/mixed-juices/.meta/design.md index 5eb2a9b48c..de569e6e9e 100644 --- a/exercises/concept/mixed-juices/.meta/design.md +++ b/exercises/concept/mixed-juices/.meta/design.md @@ -38,7 +38,6 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] The comment types mentioned below only serve as a proposal. 1. `timeToMixJuice` - - `essential`: Verify the student used a switch statement. Would be nice if we could give different feedback depending on what the student used instead. If it was if-else, comment that switch is better suited for so many different variants. @@ -53,7 +52,6 @@ The comment types mentioned below only serve as a proposal. ``` 2. `limesToCut` - - A solution that uses `if (limes.length < 0) break;` instead of combining the conditions should be considered equally correct to the exemplar solution. The version in the exemplar file is shorter but the break version emphasizes that there is a special edge case. - `essential`: Verify that `while` was used. @@ -68,7 +66,6 @@ The comment types mentioned below only serve as a proposal. - `celebratory`: Celebrate if the student used `++` and `+=`. 3. `remainingOrders` - - `essential`: Verify that do-while was used. If while was used instead, say that do-while is a better fit because there is always at least one iteration (because `timeLeft` is always > 0) and the condition can best be checked after running the code. - `essential`: Verify `timeToMixJuice` was reused instead of duplicating the code. diff --git a/exercises/concept/ozans-playlist/.meta/design.md b/exercises/concept/ozans-playlist/.meta/design.md index 79f9bc0f1e..0ae1f98a0f 100644 --- a/exercises/concept/ozans-playlist/.meta/design.md +++ b/exercises/concept/ozans-playlist/.meta/design.md @@ -35,11 +35,9 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] For all tasks, verify that the student actually used a `Set`. 1. `addTrack` - - Verify that there was no redundant `Set.has()` call 2. `deleteTrack` - - Verify that there was no redundant `Set.has()` call [analyzer]: https://github.com/exercism/javascript-analyzer From f6b496fe220c49c732b3ae5b8a0a7b77694a33ef Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:37:01 +0200 Subject: [PATCH 099/146] Update assembly-line.js --- exercises/concept/recycling-robot/assembly-line.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/concept/recycling-robot/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js index c12edca3c8..be50211d6d 100644 --- a/exercises/concept/recycling-robot/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -10,7 +10,7 @@ export class ElectronicDevice { /** * Checks if input is a boolean. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a boolean */ export function isBoolean(value) { @@ -20,7 +20,7 @@ export function isBoolean(value) { /** * Checks if input is a finite number or bigint. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { @@ -30,7 +30,7 @@ export function isNumber(value) { /** * Checks if a value is an object. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is an object. */ export function isObject(value) { @@ -40,7 +40,7 @@ export function isObject(value) { /** * Checks if a value is a numeric string. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { @@ -62,7 +62,7 @@ export function isElectronic(object) { /** * Checks if a value is a non empty array. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { @@ -74,7 +74,7 @@ export function isNonEmptyArray(value) { /** * Checks if a value is an empty array. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { From 7742dcf53148de3aa7c2b9b585a884d798a8cef5 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:37:36 +0200 Subject: [PATCH 100/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index cacde0f80a..9916094561 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -10,7 +10,7 @@ export class ElectronicDevice { /** * Checks if input is a boolean. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a boolean */ export function isBoolean(value) { @@ -20,7 +20,7 @@ export function isBoolean(value) { /** * Checks if input is a finite number or bigint. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a finite number or bigint */ export function isNumber(value) { @@ -34,7 +34,7 @@ export function isNumber(value) { /** * Checks if a value is an object. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is an object. */ export function isObject(value) { @@ -44,7 +44,7 @@ export function isObject(value) { /** * Checks if a value is a numeric string. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a numeric string. */ export function isNumericString(value) { @@ -69,7 +69,7 @@ export function isElectronic(object) { /** * Checks if a value is a non empty array. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { @@ -79,7 +79,7 @@ export function isNonEmptyArray(value) { /** * Checks if a value is an empty array. * - * @param {any} value + * @param {unknown} value * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { From f938fa0b021daf021cd792bf1047d0f4c6dc157b Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:41:35 +0200 Subject: [PATCH 101/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 9916094561..bcf7944672 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -11,7 +11,7 @@ export class ElectronicDevice { * Checks if input is a boolean. * * @param {unknown} value - * @returns {boolean} whether the input is a boolean + * @returns {value is boolean} whether the input is a boolean */ export function isBoolean(value) { return typeof value === 'boolean'; @@ -21,7 +21,7 @@ export function isBoolean(value) { * Checks if input is a finite number or bigint. * * @param {unknown} value - * @returns {boolean} whether the input is a finite number or bigint + * @returns {value is number | bigint} whether the input is a finite number or bigint */ export function isNumber(value) { return ( @@ -35,7 +35,7 @@ export function isNumber(value) { * Checks if a value is an object. * * @param {unknown} value - * @returns {boolean} whether the input is an object. + * @returns {value is object} whether the input is an object. */ export function isObject(value) { return value !== null && typeof value === 'object'; From 4544ce0ee6c9fa4a2a07aaf6b945001031b7e298 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:42:31 +0200 Subject: [PATCH 102/146] Update package.json --- exercises/concept/recycling-robot/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/package.json b/exercises/concept/recycling-robot/package.json index 91bb1a394d..6427dc32e0 100644 --- a/exercises/concept/recycling-robot/package.json +++ b/exercises/concept/recycling-robot/package.json @@ -1,5 +1,5 @@ { - "name": "@exercism/javascript-concept-assembly-line", + "name": "@exercism/javascript-concept-recycling-robot", "description": "Exercism concept exercise on type checking", "author": "Katrina Owen", "contributors": [ From 31e8328b76ef0fc1b589642d77a9768cf94aa5b7 Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 08:46:55 +0200 Subject: [PATCH 103/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index bcf7944672..8ff8bfa8ec 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -73,7 +73,7 @@ export function isElectronic(object) { * @returns {boolean} whether the input is a non empty array. */ export function isNonEmptyArray(value) { - return value instanceof Array && value.length > 0; + return Array.isArray(value) && value.length > 0; } /** @@ -83,7 +83,7 @@ export function isNonEmptyArray(value) { * @returns {boolean} whether the input is an empty array. */ export function isEmptyArray(value) { - return value instanceof Array && value.length === 0; + return Array.isArray(value) && value.length === 0; } /** From d8e48bc7bbb1d4b027285cc78b35b42d2469df4d Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 09:02:08 +0200 Subject: [PATCH 104/146] Revert "Format" This reverts commit 80110188e3dafffd39a80c655fa464b23de0608f. --- concepts/callbacks/about.md | 3 +++ concepts/closures/about.md | 2 ++ concepts/type-checking/introduction.md | 4 ++-- exercises/concept/amusement-park/.meta/design.md | 4 ++++ exercises/concept/bird-watcher/.meta/design.md | 3 +++ exercises/concept/high-score-board/.meta/design.md | 6 ++++++ exercises/concept/mixed-juices/.meta/design.md | 3 +++ exercises/concept/ozans-playlist/.meta/design.md | 2 ++ 8 files changed, 25 insertions(+), 2 deletions(-) diff --git a/concepts/callbacks/about.md b/concepts/callbacks/about.md index 1899983a55..64fca0040f 100644 --- a/concepts/callbacks/about.md +++ b/concepts/callbacks/about.md @@ -81,6 +81,7 @@ You see this pattern often when dealing with asynchronous functions to assist wi Common `Array` functions use callback functions to define their behaviour: - `Array.prototype.forEach`: + - Accepts a callback, which applies the callback to each element of an array. ```javascript @@ -91,6 +92,7 @@ Common `Array` functions use callback functions to define their behaviour: ``` - `Array.prototype.map` + - Accepts a callback, which applies the callback to each element of an array using the result to create a new array. ```javascript @@ -101,6 +103,7 @@ Common `Array` functions use callback functions to define their behaviour: ``` - `Array.prototype.reduce` + - Accepts a callback, which applies the callback to each element of an array, passing the result forward to the next invocation. ```javascript diff --git a/concepts/closures/about.md b/concepts/closures/about.md index 23cf280315..957cac692a 100644 --- a/concepts/closures/about.md +++ b/concepts/closures/about.md @@ -18,6 +18,7 @@ The name _closure_ is historically derived from [_λ-calculus_][wiki-lambda-calc ## Reasons to use closures in JavaScript 1. Data Privacy / Data Encapsulation + - Unlike other languages, in 2020, there was no way to specify _private_ variables. So closures can be used to effectively emulate _private_ variables (there was a proposal to introduce private variable notation, which might have become standard by the time you read this). ```javascript @@ -36,6 +37,7 @@ The name _closure_ is historically derived from [_λ-calculus_][wiki-lambda-calc ``` 2. Partial Application + - Functions may return functions, and when a returned function uses the argument of the function that created it, this is an example of using a closure to perform partial application. Sometimes this is called _currying_ a function. ```javascript diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index e36248750c..466cefaddb 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -4,7 +4,7 @@ Knowning what type an object has is often very important for code to run smoothl Javascript has several ways to check the type of an object. -````exercism/note +```exercism/note Javascript's type checking mechanisms can be somewhat unreliable. For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language.``` @@ -37,7 +37,7 @@ typeof [1, 2, 3, 4]; typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" -```` +``` The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. diff --git a/exercises/concept/amusement-park/.meta/design.md b/exercises/concept/amusement-park/.meta/design.md index d974fff324..ed3827a633 100644 --- a/exercises/concept/amusement-park/.meta/design.md +++ b/exercises/concept/amusement-park/.meta/design.md @@ -32,22 +32,26 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] The comment types mentioned below only serve as a proposal. 1. `createVisitor` + - `actionable`: If the student used a helper variable, give feedback that the result can be returned directly. - `celebratory`: If the student used classes, celebrate but let them know it is not necessary throughout this exercise. - `informative`: If the student did not use the short-hand notation but wrote `name: name` etc instead, let them know how to shorten that. The solution should be accepted nevertheless. 2. `revokeTicket` + - `essential`: Check the ticketId field is not deleted and re-added. - `celebratory`: If they used a method on a visitor class, celebrate but let them know it is not necessary for this exercise. 3. `ticketStatus` + - `essential`: Using a type switch should be discouraged since it is confusing to read because of the `typeof null === 'object'` quirk. - `informative`: If the student did not use early returns, maybe let them know about this alternative. - `celebratory`: Congratulate if the student used a template string for the "sold" case - `celebratory`: Congratulate if the student used a `value` helper variable. 4. `simpleTicketStatus` + - `essential`: Check `??` was used and not an if-statement or something else. - `actionable`: If the student used a helper variable, give feedback that the result can be returned directly. diff --git a/exercises/concept/bird-watcher/.meta/design.md b/exercises/concept/bird-watcher/.meta/design.md index 1b297b64d0..554e26f2c7 100644 --- a/exercises/concept/bird-watcher/.meta/design.md +++ b/exercises/concept/bird-watcher/.meta/design.md @@ -36,16 +36,19 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] For all tasks check that the student actually used a for loop. 1. `totalBirdCount` + - Verify that the condition is written with `< x.length` instead of `<= y.length -1`. - Check whether a shorthand assignment `+=` was used to increase the sum (non-essential feedback). - Verify the total was properly initialized with `0` instead of e.g. `null` - Verify the increment operator was used in loop header step 2. `birdsInWeek` + - Verify a helper variable was used instead of duplicating the calculation in the initialization and condition of the loop - Other checks should be the same as for `totalBirdCount` 3. `fixBirdCountLog` + - Check whether a shorthand assignment `+=` was used to increase the loop counter (non-essential feedback) - Check whether the increment operator was used in the loop body diff --git a/exercises/concept/high-score-board/.meta/design.md b/exercises/concept/high-score-board/.meta/design.md index 9c425cb787..45307215e9 100644 --- a/exercises/concept/high-score-board/.meta/design.md +++ b/exercises/concept/high-score-board/.meta/design.md @@ -40,27 +40,33 @@ The Concepts this exercise unlocks are: This exercise could benefit from the following rules in the [analyzer][analyzer]: 1. `createScoreBoard` + - `essential`: Make sure no class, map etc. was created, there should be just an object. - `actionable`: If the student created an empty object first and then added the value, give feedback to include the entry in the object literal directly. - `actionable`: Check that the object was returned directly, no intermediate assignment to a variable necessary. 2. `addPlayer` + - `essential`: Check the assignment operator was used and no additional variables were declared. 3. `removePlayer` + - `essential`: Make sure `delete` was used and not set to undefined or null. - `actionable`: If there is additional code to check whether the key is present before deleting it, give feedback that this is not necessary. 4. `updateScore` + - `actionable`: If the student used a separate variable to calculate the new value first, tell them it is not necessary. - `actionable`: If the student did not use the shorthand assignment operator, tell them about it. If they used it already, give a `celebratory` comment. 5. `applyMondayBonus` + - `essential`: Check the student actually used `for...in`. - Same feedback as in `updateScore` applies. - Using `updateScore` in the solution should be treated as equally correct as the exemplar solution. 6. `normalizeScore` + - `actionable`: No intermediate variables necessary. ## Notes diff --git a/exercises/concept/mixed-juices/.meta/design.md b/exercises/concept/mixed-juices/.meta/design.md index de569e6e9e..5eb2a9b48c 100644 --- a/exercises/concept/mixed-juices/.meta/design.md +++ b/exercises/concept/mixed-juices/.meta/design.md @@ -38,6 +38,7 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] The comment types mentioned below only serve as a proposal. 1. `timeToMixJuice` + - `essential`: Verify the student used a switch statement. Would be nice if we could give different feedback depending on what the student used instead. If it was if-else, comment that switch is better suited for so many different variants. @@ -52,6 +53,7 @@ The comment types mentioned below only serve as a proposal. ``` 2. `limesToCut` + - A solution that uses `if (limes.length < 0) break;` instead of combining the conditions should be considered equally correct to the exemplar solution. The version in the exemplar file is shorter but the break version emphasizes that there is a special edge case. - `essential`: Verify that `while` was used. @@ -66,6 +68,7 @@ The comment types mentioned below only serve as a proposal. - `celebratory`: Celebrate if the student used `++` and `+=`. 3. `remainingOrders` + - `essential`: Verify that do-while was used. If while was used instead, say that do-while is a better fit because there is always at least one iteration (because `timeLeft` is always > 0) and the condition can best be checked after running the code. - `essential`: Verify `timeToMixJuice` was reused instead of duplicating the code. diff --git a/exercises/concept/ozans-playlist/.meta/design.md b/exercises/concept/ozans-playlist/.meta/design.md index 0ae1f98a0f..79f9bc0f1e 100644 --- a/exercises/concept/ozans-playlist/.meta/design.md +++ b/exercises/concept/ozans-playlist/.meta/design.md @@ -35,9 +35,11 @@ This exercise could benefit from the following rules in the [analyzer][analyzer] For all tasks, verify that the student actually used a `Set`. 1. `addTrack` + - Verify that there was no redundant `Set.has()` call 2. `deleteTrack` + - Verify that there was no redundant `Set.has()` call [analyzer]: https://github.com/exercism/javascript-analyzer From 2742e1d76e743c3cfebd203c220a7f81a56dfbce Mon Sep 17 00:00:00 2001 From: J R M Date: Thu, 10 Jul 2025 09:05:28 +0200 Subject: [PATCH 105/146] Format --- concepts/type-checking/introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index 466cefaddb..e36248750c 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -4,7 +4,7 @@ Knowning what type an object has is often very important for code to run smoothl Javascript has several ways to check the type of an object. -```exercism/note +````exercism/note Javascript's type checking mechanisms can be somewhat unreliable. For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language.``` @@ -37,7 +37,7 @@ typeof [1, 2, 3, 4]; typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" -``` +```` The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. From 2c0358cfa0ebef773f79cdcc75dad51bf228c31d Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:24:34 +0200 Subject: [PATCH 106/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 9e0c515f34..1985616317 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -13,7 +13,8 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator The `typeof` operator returns the type of its input. -The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +It can also be `"function"` or `"object"`. ```javascript typeof undefined; From 44072bd403eb014ae15ad03dbebce91b38ea044c Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:24:52 +0200 Subject: [PATCH 107/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 1985616317..10997947d0 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -12,7 +12,7 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator -The `typeof` operator returns the type of its input. +The `typeof` operator returns the type of its operand. The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. It can also be `"function"` or `"object"`. From 6f0f146b479f15c97ac356ee40596a0c282ee831 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:25:34 +0200 Subject: [PATCH 108/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 10997947d0..3cc3b26ab6 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -41,7 +41,7 @@ typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" ``` -The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. +For [historical reasons][`typeof null` is `"object"`]. ## The `instanceof` operator From faa6fea598644d63e419822b707f86d038db9c18 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:26:01 +0200 Subject: [PATCH 109/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 3cc3b26ab6..47d5aae589 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -46,7 +46,7 @@ For [historical reasons][`typeof null` is `"object"`]. ## The `instanceof` operator For checking the type of an object, you can use the `instanceof` operator. -It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +It evaluates into a `boolean` depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. `instanceof` only works for compound data types, such as arrays and objects. From d41997d8f21863fca7cd53f764535cb14a4ca4a6 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:33:12 +0200 Subject: [PATCH 110/146] Update about.md --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 47d5aae589..7aca488160 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -48,7 +48,7 @@ For [historical reasons][`typeof null` is `"object"`]. For checking the type of an object, you can use the `instanceof` operator. It evaluates into a `boolean` depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. -`instanceof` only works for compound data types, such as arrays and objects. +`instanceof` only works on objects. ```javascript class Beverage { From d5c4fb0913693bebe3ada7a94ce459205798a265 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:36:21 +0200 Subject: [PATCH 111/146] Update about.md --- concepts/type-checking/about.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 7aca488160..78cd23bfd9 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -54,10 +54,12 @@ To clarify, `instanceof` will return whether the first operand is an instance of class Beverage { // ... } + // The Coffee class is a child of the Beverage class. class Coffee extends Beverage { // ... } + const java = new Coffee(); java instanceof Coffee; @@ -87,10 +89,12 @@ class Coffee { this.temperature = 'hot'; this.isDarkMatter = undefined; } + coolDown() { this.temperature = 'warm'; } } + const espresso = new Coffee(); 'temperature' in espresso; @@ -124,6 +128,7 @@ class Coffee { constructor() { this.temperature = 'hot'; } + coolDown() { this.temperature = 'warm'; } From c44db51128952f6b147d4c23432e1e217b0711c3 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:37:20 +0200 Subject: [PATCH 112/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 78cd23bfd9..682f05d2c0 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -72,7 +72,7 @@ java instanceof Beverage; ```exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. -While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. +While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. From 0c4d4428823fb719192530023b6b49b586b7ac2c Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:37:37 +0200 Subject: [PATCH 113/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 682f05d2c0..932f2dbb4b 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -74,7 +74,7 @@ The `Array` class has a method called `Array.isArray()` that checks if its argum While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. -This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +This is because the Array class has a different constructor in each realm, and each `iframe` has its own ream, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. ``` From 7780f5c37cbec3fba60f083945859bd6723f673b Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:37:51 +0200 Subject: [PATCH 114/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 932f2dbb4b..6b89ced867 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -76,6 +76,16 @@ While `instanceof Array` will not work with an array created in a different real This is because the Array class has a different constructor in each realm, and each `iframe` has its own ream, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. + +It can also survive false positives where an object isn't actually an `Array`, and merely has `Array` in its prototype chain. + +```javascript +({ __proto__: Array.prototype }) instanceof Array +// => true + +Array.isArray({ __proto__: Array.prototype }) +// => false +``` ``` ## The `in` operator From 88da8ba2903981ee99edbf93125a9a7e708cf4c4 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:38:07 +0200 Subject: [PATCH 115/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 6b89ced867..22e50adb9c 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -91,7 +91,8 @@ Array.isArray({ __proto__: Array.prototype }) ## The `in` operator The `in` operator returns whether the first operand is a property of the second operand. -It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. +It does not check that the property has a defined value. +A property set to `undefined` will still be detected by `in`. ```javascript class Coffee { From 803f3c16836307acd72a5f1059f93b36678ca37d Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:38:24 +0200 Subject: [PATCH 116/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 22e50adb9c..3d71763d88 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -119,7 +119,8 @@ const espresso = new Coffee(); ``` ````exercism/note -`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +`in` will return `true` for inherited properties and methods. + ```javascript "coolDown" in espresso // => true @@ -127,7 +128,8 @@ const espresso = new Coffee(); "constructor" in espresso // => true ``` -To avoid this, use the hasOwnProperty() method. + +To avoid this, use `Object.hasOwn()` instead ```` ## The `Object.hasOwn()` function From fccfddc0f9c27d84919f1ede78ebfb96149776d4 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:38:59 +0200 Subject: [PATCH 117/146] Update concepts/type-checking/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 3d71763d88..a2daf20495 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -134,7 +134,7 @@ To avoid this, use `Object.hasOwn()` instead ## The `Object.hasOwn()` function -The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object _owns the given property_ (it is not inherited or a method). ```javascript class Coffee { From 741916f41d4d31f862216d6de5ada8fa4b476517 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:40:40 +0200 Subject: [PATCH 118/146] Update introduction.md --- concepts/type-checking/introduction.md | 52 ++++++++++++++++++-------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index e36248750c..a2daf20495 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -1,18 +1,20 @@ # About -Knowning what type an object has is often very important for code to run smoothly and without errors. +Knowning what the type of a piece of data is, is often very important for code to run smoothly and without errors. -Javascript has several ways to check the type of an object. +Javascript has several ways to check the type of a value or object. -````exercism/note +```exercism/note Javascript's type checking mechanisms can be somewhat unreliable. -For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language.``` +For better type safety and stronger types, you should probably use TypeScript, a language that builds on JavaScript, but with the type syntax of a static-typed language. +``` ## The `typeof` operator -The `typeof` operator returns the type of its input. -The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. +The `typeof` operator returns the type of its operand. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +It can also be `"function"` or `"object"`. ```javascript typeof undefined; @@ -37,25 +39,27 @@ typeof [1, 2, 3, 4]; typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" -```` +``` -The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. +For [historical reasons][`typeof null` is `"object"`]. ## The `instanceof` operator For checking the type of an object, you can use the `instanceof` operator. -It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +It evaluates into a `boolean` depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. -`instanceof` only works for compound data types, such as arrays and objects. +`instanceof` only works on objects. ```javascript class Beverage { // ... } + // The Coffee class is a child of the Beverage class. class Coffee extends Beverage { // ... } + const java = new Coffee(); java instanceof Coffee; @@ -68,16 +72,27 @@ java instanceof Beverage; ```exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. -While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. +While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. -This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +This is because the Array class has a different constructor in each realm, and each `iframe` has its own ream, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. + +It can also survive false positives where an object isn't actually an `Array`, and merely has `Array` in its prototype chain. + +```javascript +({ __proto__: Array.prototype }) instanceof Array +// => true + +Array.isArray({ __proto__: Array.prototype }) +// => false +``` ``` ## The `in` operator The `in` operator returns whether the first operand is a property of the second operand. -It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. +It does not check that the property has a defined value. +A property set to `undefined` will still be detected by `in`. ```javascript class Coffee { @@ -85,10 +100,12 @@ class Coffee { this.temperature = 'hot'; this.isDarkMatter = undefined; } + coolDown() { this.temperature = 'warm'; } } + const espresso = new Coffee(); 'temperature' in espresso; @@ -102,7 +119,8 @@ const espresso = new Coffee(); ``` ````exercism/note -`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +`in` will return `true` for inherited properties and methods. + ```javascript "coolDown" in espresso // => true @@ -110,18 +128,20 @@ const espresso = new Coffee(); "constructor" in espresso // => true ``` -To avoid this, use the hasOwnProperty() method. + +To avoid this, use `Object.hasOwn()` instead ```` ## The `Object.hasOwn()` function -The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object _owns the given property_ (it is not inherited or a method). ```javascript class Coffee { constructor() { this.temperature = 'hot'; } + coolDown() { this.temperature = 'warm'; } From ae0ef2e85d9370516540189c8841962af4962b71 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:41:38 +0200 Subject: [PATCH 119/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index b863e655c4..8a572dc3ec 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -18,7 +18,7 @@ isBoolean(null); ### 2. Check if a value is a number. -Implement the `isNumber` function, that checks if a value is a _finite_ number or bigint, ie not `NaN` or `Infinity`. +Implement the `isNumber` function, that checks if a value is a _finite_ `number` or `bigint`, ie. not `NaN` or `Infinity`. Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. Your function should be able to correctly handle this as well. From 49da298bde9b713d510ce72576f6e7caeb3ed28f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 08:59:37 +0200 Subject: [PATCH 120/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 8a572dc3ec..5ca285890b 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -20,7 +20,7 @@ isBoolean(null); Implement the `isNumber` function, that checks if a value is a _finite_ `number` or `bigint`, ie. not `NaN` or `Infinity`. -Sometimes, the device for reading IDs bugs and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. +Sometimes, the device for reading IDs fails and reads a non-numeric value as `NaN` (Not a Number) or `Infinity`. Your function should be able to correctly handle this as well. ```javascript From e078be7454b58a3452bf4321ca52cfd6081c3cf4 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:01:05 +0200 Subject: [PATCH 121/146] Update instructions.md From 0c832fec91bbd88ef7d06dbc184ace8dfbfb1fdb Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:01:40 +0200 Subject: [PATCH 122/146] Update instructions.md --- exercises/concept/recycling-robot/.docs/instructions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 5ca285890b..d7a0d0fc55 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -39,7 +39,8 @@ isNumber(NaN); ### 3. Check if a value is an object -Implement the `isObject` function, that should check if the value is actually an object, not null. +Implement the `isObject` function, that should check if the value is an object. +On the conveyor, `null` is nothing and not considered an object. ```javascript isObject({ greeting: 'Hello' }); From 4e50a012b0f2e8533dceae1fd87705fc90b1829b Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:02:04 +0200 Subject: [PATCH 123/146] Update instructions.md --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index d7a0d0fc55..8a7d19ede8 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -52,7 +52,7 @@ isObject(25n); ### 4. Check if a string is numeric -Implement the `isNumericString` function, that should check if the value is a string but only consists of numbers. +Implement the `isNumericString` function, that should check if the value is a string that only consists of digits. ```javascript isNumericString(42); From 62682d5f112e5390d56d04285fdfabb5e3d6c761 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:02:27 +0200 Subject: [PATCH 124/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 8a7d19ede8..cbddab3076 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -67,7 +67,7 @@ isNumericString('Hi!'); ### 5. Check if an object is electronic -Implement the `isElectronic` function, that checks if an object is an instance of the provided ElectronicDevice class or one of its child classes. +Implement the `isElectronic` function, that checks if an object is an instance of the provided `ElectronicDevice` class or one of its child classes. ```javascript class Duck { From 712c34facc8862e9e11022543a7ff88aeab58ea7 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:03:01 +0200 Subject: [PATCH 125/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index cbddab3076..8bb95cf45a 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -73,9 +73,11 @@ Implement the `isElectronic` function, that checks if an object is an instance o class Duck { //... } + class WashingMachine extends ElectronicDevice { //... } + isElectronic(new Duck()); // => false From a0f5dff7c3ed539c587cded0bc86de18aba6a115 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:03:43 +0200 Subject: [PATCH 126/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 8bb95cf45a..055b9b249b 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -87,7 +87,7 @@ isElectronic(new WashingMachine()); ### 6. Check if a value is a non empty array -Implement the `isNonEmptyArray` function, that checks if an object is a non empty array. +Implement the `isNonEmptyArray` function, that checks if a value is a non-empty array. ```javascript isNonEmptyArray([1, 2, 3]); From c820258a2b5f188e65a72a1a750e1af8da8e2be0 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:05:09 +0200 Subject: [PATCH 127/146] Update exercises/concept/recycling-robot/.docs/instructions.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/instructions.md b/exercises/concept/recycling-robot/.docs/instructions.md index 055b9b249b..1ed7f89b40 100644 --- a/exercises/concept/recycling-robot/.docs/instructions.md +++ b/exercises/concept/recycling-robot/.docs/instructions.md @@ -99,7 +99,7 @@ isNonEmptyArray([]); ### 7. Check if a value is an empty array -Implement the `isEmptyArray` function, that checks if an object is an empty array. +Implement the `isEmptyArray` function, that checks if a value is an empty array. ```javascript isEmptyArray([1, 2, 3]); From 784a2aee7962ef31ccd66478f7f58dbaa0e658c8 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:07:24 +0200 Subject: [PATCH 128/146] Update config.json --- config.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config.json b/config.json index f447dba22b..a8809441bc 100644 --- a/config.json +++ b/config.json @@ -446,6 +446,10 @@ ], "prerequisites": [ "basics", + "errors", + "objects", + "arrays", + "classes", "inheritance" ] } From 61efdc4897cbbe0ae713e1668f6e744390b5ece7 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:07:44 +0200 Subject: [PATCH 129/146] Update exercises/concept/recycling-robot/.docs/introduction.md Co-authored-by: Derk-Jan Karrenbeld --- exercises/concept/recycling-robot/.docs/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index 60ca3779e6..6e8d88930a 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -1,4 +1,4 @@ -# About +# Introduction Knowning what type an object has is often very important for code to run smoothly and without errors. From 97a5c2293dd5a02244833747ec328be33bbab953 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:09:04 +0200 Subject: [PATCH 130/146] Update introduction.md --- .../recycling-robot/.docs/introduction.md | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index 6e8d88930a..40ba27a9eb 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -1,8 +1,8 @@ # Introduction -Knowning what type an object has is often very important for code to run smoothly and without errors. +Knowning what the type of a piece of data is, is often very important for code to run smoothly and without errors. -Javascript has several ways to check the type of an object. +Javascript has several ways to check the type of a value or object. ```exercism/note Javascript's type checking mechanisms can be somewhat unreliable. @@ -12,8 +12,9 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator -The `typeof` operator returns the type of its input. -The output is restricted to one of the [primitive data types][primitives], `"function"` or `"object"`. +The `typeof` operator returns the type of its operand. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +It can also be `"function"` or `"object"`. ```javascript typeof undefined; @@ -40,23 +41,25 @@ typeof { city: 'Stockholm', country: 'Sweden' }; // => "object" ``` -The one exception to this is that `typeof null` returns `"object"` for [historical reasons][typeof null is object]. +For [historical reasons][`typeof null` is `"object"`]. ## The `instanceof` operator For checking the type of an object, you can use the `instanceof` operator. -It returns a boolean depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. +It evaluates into a `boolean` depending on whether the second operand is included in the first operands' [prototype chain][prototype chain]. To clarify, `instanceof` will return whether the first operand is an instance of second operand or one of its child classes. -`instanceof` only works for compound data types, such as arrays and objects. +`instanceof` only works on objects. ```javascript class Beverage { // ... } + // The Coffee class is a child of the Beverage class. class Coffee extends Beverage { // ... } + const java = new Coffee(); java instanceof Coffee; @@ -69,16 +72,27 @@ java instanceof Beverage; ```exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. -While `instanceof Array` will not work with an array created in a different `iframe` in a webpage, `Array.isArray()` will. +While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. -This is because the Array class has a different constructor in each `iframe`, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. +This is because the Array class has a different constructor in each realm, and each `iframe` has its own ream, meaning that the function in the prototype chain will be different, causing `instanceof Array` to fail. `Array.isArray()` is capable of ignoring this, and should always be used when possible. + +It can also survive false positives where an object isn't actually an `Array`, and merely has `Array` in its prototype chain. + +```javascript +({ __proto__: Array.prototype }) instanceof Array +// => true + +Array.isArray({ __proto__: Array.prototype }) +// => false +``` ``` ## The `in` operator The `in` operator returns whether the first operand is a property of the second operand. -It does not check that the property is defined, a property set to `undefined` will still be detected by `in`. +It does not check that the property has a defined value. +A property set to `undefined` will still be detected by `in`. ```javascript class Coffee { @@ -86,10 +100,12 @@ class Coffee { this.temperature = 'hot'; this.isDarkMatter = undefined; } + coolDown() { this.temperature = 'warm'; } } + const espresso = new Coffee(); 'temperature' in espresso; @@ -103,7 +119,8 @@ const espresso = new Coffee(); ``` ````exercism/note -`in` can be slightly unreliable, as it will return `true` for inherited properties and methods. +`in` will return `true` for inherited properties and methods. + ```javascript "coolDown" in espresso // => true @@ -111,18 +128,20 @@ const espresso = new Coffee(); "constructor" in espresso // => true ``` -To avoid this, use the hasOwnProperty() method. + +To avoid this, use `Object.hasOwn()` instead ```` ## The `Object.hasOwn()` function -The `Object.hasOwn()` method returns whether the specified object has _its own property_ (not inherited or a method) that matches a string. +The `Object.hasOwn()` method returns whether the specified object _owns the given property_ (it is not inherited or a method). ```javascript class Coffee { constructor() { this.temperature = 'hot'; } + coolDown() { this.temperature = 'warm'; } From 5608f6b6e694e0a4fc12ec8bca4f7a521777d3a3 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:10:14 +0200 Subject: [PATCH 131/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 8ff8bfa8ec..b552dce9bb 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -26,7 +26,7 @@ export function isBoolean(value) { export function isNumber(value) { return ( (typeof value === 'number' || typeof value === 'bigint') && - !isNaN(Number(value)) && + !isNaN(value) && value !== Infinity ); } From a5cd0c1e0e04a677217e3367774778c1da13e914 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:12:07 +0200 Subject: [PATCH 132/146] Update config.json --- exercises/concept/recycling-robot/.meta/config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exercises/concept/recycling-robot/.meta/config.json b/exercises/concept/recycling-robot/.meta/config.json index 7f4a1f696f..dce077e5e2 100644 --- a/exercises/concept/recycling-robot/.meta/config.json +++ b/exercises/concept/recycling-robot/.meta/config.json @@ -11,6 +11,9 @@ ], "exemplar": [ ".meta/exemplar.js" + ], + "editor": [ + "lib.js" ] }, "blurb": "Learn about type checking while helping manage an assembly line" From 64a95aa54da73b1a57ea6bea80680caff9a79d75 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:12:19 +0200 Subject: [PATCH 133/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index b552dce9bb..27a1e591ca 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -4,9 +4,6 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -export class ElectronicDevice { - // This class will be used in the exercise. -} /** * Checks if input is a boolean. * From 5dda1a05f5850d09a1961aac9001e330e59c6a63 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:12:33 +0200 Subject: [PATCH 134/146] Update assembly-line.js --- exercises/concept/recycling-robot/assembly-line.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/exercises/concept/recycling-robot/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js index be50211d6d..808ecdc41f 100644 --- a/exercises/concept/recycling-robot/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -4,9 +4,6 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -export class ElectronicDevice { - // This class will be used in the exercise. -} /** * Checks if input is a boolean. * From 9fa8ebc0ad2c0e7549d6003395d92fa373aa5a1f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:12:59 +0200 Subject: [PATCH 135/146] Create lib.js --- exercises/concept/recycling-robot/lib.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 exercises/concept/recycling-robot/lib.js diff --git a/exercises/concept/recycling-robot/lib.js b/exercises/concept/recycling-robot/lib.js new file mode 100644 index 0000000000..b0c1963e75 --- /dev/null +++ b/exercises/concept/recycling-robot/lib.js @@ -0,0 +1,3 @@ +export class ElectronicDevice { + // This class will be used in the exercise. +} From 63375b1c57a028b63f22c60bcb3d0f6b8b120fe9 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:14:20 +0200 Subject: [PATCH 136/146] Update assembly-line.js --- exercises/concept/recycling-robot/assembly-line.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/concept/recycling-robot/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js index 808ecdc41f..8cec68b7a1 100644 --- a/exercises/concept/recycling-robot/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -4,6 +4,8 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. +import {ElectronicDevice} from "./lib.js" + /** * Checks if input is a boolean. * From 7a945a6eacc5235dfd1c80adf1146645405a57d9 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:15:24 +0200 Subject: [PATCH 137/146] Update assembly-line.spec.js --- exercises/concept/recycling-robot/assembly-line.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/assembly-line.spec.js b/exercises/concept/recycling-robot/assembly-line.spec.js index b470bdfe8a..484ed5d771 100644 --- a/exercises/concept/recycling-robot/assembly-line.spec.js +++ b/exercises/concept/recycling-robot/assembly-line.spec.js @@ -4,7 +4,6 @@ import { isNumber, isObject, isNumericString, - ElectronicDevice, isElectronic, isNonEmptyArray, isEmptyArray, @@ -13,6 +12,7 @@ import { hasIdProperty, hasDefinedType, } from './assembly-line'; +import {ElectronicDevice} from './lib.js' describe('isBoolean', () => { test('isBoolean works on booleans', () => { expect(isBoolean(true)).toBe(true); From e28b1edec6fa253f3af791760fc08182615b14f8 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:16:33 +0200 Subject: [PATCH 138/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 27a1e591ca..0161c37bf0 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -4,6 +4,8 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. +import {ElectronicDevice} from "./lib.js" + /** * Checks if input is a boolean. * From 750c9678bbad782f258a1a434f263b353b1e8e8b Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:19:01 +0200 Subject: [PATCH 139/146] Update exemplar.js --- exercises/concept/recycling-robot/.meta/exemplar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 0161c37bf0..0c34a31253 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -25,7 +25,7 @@ export function isBoolean(value) { export function isNumber(value) { return ( (typeof value === 'number' || typeof value === 'bigint') && - !isNaN(value) && + !isNaN(Number(value)) && value !== Infinity ); } From 5176daa644df7fc2dddbdeb0a45cf57cbe42c11b Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:21:15 +0200 Subject: [PATCH 140/146] Configlet format --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index a8809441bc..ddc35cb96d 100644 --- a/config.json +++ b/config.json @@ -446,7 +446,7 @@ ], "prerequisites": [ "basics", - "errors", + "errors", "objects", "arrays", "classes", From 1fe14cf90ddf353b6c088b95ea3fbb2f2b70261f Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 09:22:38 +0200 Subject: [PATCH 141/146] nodejs format --- concepts/type-checking/about.md | 11 ++++++----- concepts/type-checking/introduction.md | 11 ++++++----- .../concept/recycling-robot/.docs/introduction.md | 11 ++++++----- exercises/concept/recycling-robot/.meta/exemplar.js | 2 +- exercises/concept/recycling-robot/assembly-line.js | 2 +- .../concept/recycling-robot/assembly-line.spec.js | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index a2daf20495..7e21eb10da 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -13,7 +13,7 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator The `typeof` operator returns the type of its operand. -The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. It can also be `"function"` or `"object"`. ```javascript @@ -69,7 +69,7 @@ java instanceof Beverage; // => true ``` -```exercism/advanced +````exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. @@ -85,8 +85,9 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -``` -``` +```` + +```` ## The `in` operator @@ -116,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -``` +```` ````exercism/note `in` will return `true` for inherited properties and methods. diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index a2daf20495..7e21eb10da 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -13,7 +13,7 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator The `typeof` operator returns the type of its operand. -The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. It can also be `"function"` or `"object"`. ```javascript @@ -69,7 +69,7 @@ java instanceof Beverage; // => true ``` -```exercism/advanced +````exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. @@ -85,8 +85,9 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -``` -``` +```` + +```` ## The `in` operator @@ -116,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -``` +```` ````exercism/note `in` will return `true` for inherited properties and methods. diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index 40ba27a9eb..0e2bb5e94a 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -13,7 +13,7 @@ For better type safety and stronger types, you should probably use TypeScript, a ## The `typeof` operator The `typeof` operator returns the type of its operand. -The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. +The output is a string matching the name of one of the [primitive data types][primitives], except for `"null"`. It can also be `"function"` or `"object"`. ```javascript @@ -69,7 +69,7 @@ java instanceof Beverage; // => true ``` -```exercism/advanced +````exercism/advanced The `Array` class has a method called `Array.isArray()` that checks if its argument is an array. While `instanceof Array` will not work with an array created in a different realm such as an `iframe` in a webpage, `Array.isArray()` will. @@ -85,8 +85,9 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -``` -``` +```` + +```` ## The `in` operator @@ -116,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -``` +```` ````exercism/note `in` will return `true` for inherited properties and methods. diff --git a/exercises/concept/recycling-robot/.meta/exemplar.js b/exercises/concept/recycling-robot/.meta/exemplar.js index 0c34a31253..28b8b48beb 100644 --- a/exercises/concept/recycling-robot/.meta/exemplar.js +++ b/exercises/concept/recycling-robot/.meta/exemplar.js @@ -4,7 +4,7 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -import {ElectronicDevice} from "./lib.js" +import { ElectronicDevice } from './lib.js'; /** * Checks if input is a boolean. diff --git a/exercises/concept/recycling-robot/assembly-line.js b/exercises/concept/recycling-robot/assembly-line.js index 8cec68b7a1..65727895a5 100644 --- a/exercises/concept/recycling-robot/assembly-line.js +++ b/exercises/concept/recycling-robot/assembly-line.js @@ -4,7 +4,7 @@ // the @ts-check directive. It will give you helpful autocompletion when // implementing this exercise. -import {ElectronicDevice} from "./lib.js" +import { ElectronicDevice } from './lib.js'; /** * Checks if input is a boolean. diff --git a/exercises/concept/recycling-robot/assembly-line.spec.js b/exercises/concept/recycling-robot/assembly-line.spec.js index 484ed5d771..93caa92725 100644 --- a/exercises/concept/recycling-robot/assembly-line.spec.js +++ b/exercises/concept/recycling-robot/assembly-line.spec.js @@ -12,7 +12,7 @@ import { hasIdProperty, hasDefinedType, } from './assembly-line'; -import {ElectronicDevice} from './lib.js' +import { ElectronicDevice } from './lib.js'; describe('isBoolean', () => { test('isBoolean works on booleans', () => { expect(isBoolean(true)).toBe(true); From c46d980de13098d6f301c7468ac8a4ab88548ec2 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 14:32:33 +0200 Subject: [PATCH 142/146] Update config.json --- exercises/concept/recycling-robot/.meta/config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/concept/recycling-robot/.meta/config.json b/exercises/concept/recycling-robot/.meta/config.json index dce077e5e2..aec5af47a5 100644 --- a/exercises/concept/recycling-robot/.meta/config.json +++ b/exercises/concept/recycling-robot/.meta/config.json @@ -1,6 +1,7 @@ { "authors": [ - "quintuple-mallard" + "quintuple-mallard", + "SleeplessByte" ], "files": { "solution": [ From 23355e66998f165ce72c672aacb1fdc7c8cbf5f8 Mon Sep 17 00:00:00 2001 From: J R M Date: Fri, 11 Jul 2025 14:32:49 +0200 Subject: [PATCH 143/146] Update config.json --- concepts/type-checking/.meta/config.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/concepts/type-checking/.meta/config.json b/concepts/type-checking/.meta/config.json index f96e488604..72261751ff 100644 --- a/concepts/type-checking/.meta/config.json +++ b/concepts/type-checking/.meta/config.json @@ -1,5 +1,8 @@ { "blurb": "Learn how to check the type of a value or object in JavaScript", - "authors": ["quintuple-mallard"], + "authors": [ + "quintuple-mallard", + "SleeplessByte" + ], "contributors": [] } From 12fe19a625ac590eaabf50c09b62fab386f5ab5d Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 11 Jul 2025 23:23:03 +0200 Subject: [PATCH 144/146] Apply suggestions from code review --- concepts/type-checking/introduction.md | 2 +- .../concept/recycling-robot/.docs/introduction.md | 2 +- .../concept/recycling-robot/assembly-line.spec.js | 12 ++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index 7e21eb10da..4297629069 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -85,7 +85,7 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -```` +``` ```` diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index 0e2bb5e94a..eb1b89d839 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -85,7 +85,7 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -```` +``` ```` diff --git a/exercises/concept/recycling-robot/assembly-line.spec.js b/exercises/concept/recycling-robot/assembly-line.spec.js index 93caa92725..e23b6dc463 100644 --- a/exercises/concept/recycling-robot/assembly-line.spec.js +++ b/exercises/concept/recycling-robot/assembly-line.spec.js @@ -13,6 +13,7 @@ import { hasDefinedType, } from './assembly-line'; import { ElectronicDevice } from './lib.js'; + describe('isBoolean', () => { test('isBoolean works on booleans', () => { expect(isBoolean(true)).toBe(true); @@ -26,6 +27,7 @@ describe('isBoolean', () => { expect(isBoolean(Symbol('1'))).toBe(false); }); }); + describe('isNumber', () => { test('isNumber works on numbers', () => { expect(isNumber(42)).toBe(true); @@ -49,6 +51,7 @@ describe('isNumber', () => { expect(isNumber(Infinity)).toBe(false); }); }); + class ClassForTesting { constructor(number, word) { this.number = number; @@ -56,6 +59,7 @@ class ClassForTesting { } id() {} } + describe('isObject', () => { test('isObject works on objects', () => { expect(isObject({})).toBe(true); @@ -77,6 +81,7 @@ describe('isObject', () => { expect(isObject(null)).toBe(false); }); }); + describe('isNumericString', () => { test('isNumericString works on numeric strings', () => { expect(isNumericString('42')).toBe(true); @@ -95,10 +100,12 @@ describe('isNumericString', () => { expect(isNumericString(Symbol('\u0070'))).toBe(false); }); }); + class Oven extends ElectronicDevice {} class Computer extends ElectronicDevice {} class PersonalComputer extends Computer {} class HomeMadePersonalComputer extends PersonalComputer {} + describe('isElectronic', () => { test('isElectronic works on instances of ElectronicDevice or its child classes', () => { expect(isElectronic(new ElectronicDevice())).toBe(true); @@ -124,6 +131,7 @@ describe('isElectronic', () => { expect(isElectronic(new HomeMadePersonalComputer())).toBe(true); }); }); + describe('isNonEmptyArray', () => { test('isNonEmptyArray works on non-empty arrays', () => { expect(isNonEmptyArray([1, 2, 3])).toBe(true); @@ -152,9 +160,11 @@ describe('isEmptyArray', () => { expect(isEmptyArray(123)).toBe(false); }); }); + class TestAssertHasId { id() {} } + describe('assertHasId', () => { test("assertHasId throws error if object has no 'id' property or method", () => { expect(() => assertHasId({})).toThrow(); @@ -164,9 +174,11 @@ describe('assertHasId', () => { expect(() => assertHasId(new TestAssertHasId())).not.toThrow(); }); }); + class TestHasType { type() {} } + describe('hasType', () => { test('hasType works correctly', () => { expect(hasType({ type: 'example' })).toBe(true); From b4c172d0a523e3902a39b3e22120f4241a14fa78 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 11 Jul 2025 23:23:30 +0200 Subject: [PATCH 145/146] Update concepts/type-checking/about.md --- concepts/type-checking/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 7e21eb10da..4297629069 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -85,7 +85,7 @@ It can also survive false positives where an object isn't actually an `Array`, a Array.isArray({ __proto__: Array.prototype }) // => false -```` +``` ```` From ff4f08fe55f158b0bd4b73ab556256db456eee39 Mon Sep 17 00:00:00 2001 From: Derk-Jan Karrenbeld Date: Fri, 11 Jul 2025 23:25:31 +0200 Subject: [PATCH 146/146] Format --- concepts/type-checking/about.md | 2 +- concepts/type-checking/introduction.md | 2 +- exercises/concept/recycling-robot/.docs/introduction.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/concepts/type-checking/about.md b/concepts/type-checking/about.md index 4297629069..d855cc9dda 100644 --- a/concepts/type-checking/about.md +++ b/concepts/type-checking/about.md @@ -117,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -```` +``` ````exercism/note `in` will return `true` for inherited properties and methods. diff --git a/concepts/type-checking/introduction.md b/concepts/type-checking/introduction.md index 4297629069..d855cc9dda 100644 --- a/concepts/type-checking/introduction.md +++ b/concepts/type-checking/introduction.md @@ -117,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -```` +``` ````exercism/note `in` will return `true` for inherited properties and methods. diff --git a/exercises/concept/recycling-robot/.docs/introduction.md b/exercises/concept/recycling-robot/.docs/introduction.md index eb1b89d839..21f826324b 100644 --- a/exercises/concept/recycling-robot/.docs/introduction.md +++ b/exercises/concept/recycling-robot/.docs/introduction.md @@ -117,7 +117,7 @@ const espresso = new Coffee(); 'isDarkMatter' in espresso; // => true -```` +``` ````exercism/note `in` will return `true` for inherited properties and methods.