Posted onEdited onInjavascript Symbols count in article: 285Reading time ≈1 mins.
How logical or || operator works in JavaScript
Consider the following expression, what’s the evaluated result?
1
`expr1 || expr2`
If expr1 can be converted to true, return expr1. Otherwise, return expr2. So we have the following truth:
1 2 3 4 5 6 7 8 9 10
true || true; // t || t returns true false || true; // f || t returns true true || false; // t || f returns true false || 3 === 4; // f || f returns false "Cat" || "Dog"; // t || t returns "Cat" false || "Cat"; // f || t returns "Cat" "Cat" || false; // t || f returns "Cat" "" || false; // f || f returns false false || ""; // f || f returns "" false || varObject; // f || object returns varObject
|| in javascript not always return boolean(true or false)
Note that || in javascript is quit difference from || in other languages. For example, in Java, || returns Boolean(true or false), but in JavaScript, it returns the value of one of the operands.
1 2
"" || 1; // returns 1 false || ""; // returns ""
If you want to convert the value to boolean, you can use double !! or Boolean()
!!expr - convert to boolean
Boolean(expr) - convert to boolean
Short circuit
|| is a short-circuit operator, which means if the first operand is true, it will not evaluate the second operand.
1
true || console.log("Hello"); // nothing output
|| vs ??
|| and ?? are both used to provide a default value, but they have different behaviors, if you only care about null or undefined, and treat other Falsy value as valid(for example 0 or empty string "") use ??, otherwise, use ||.
1 2 3 4 5 6 7
const x = 0; const y = x || 10; // y = 10 const z = x ?? 10; // z = 0
const a = ""; const b = a || "default"; // b = "default" const c = a ?? "default"; // c = ""
Posted onEdited onInjavascript Symbols count in article: 140Reading time ≈1 mins.
In JavaScript, the nullish operator ?? is used to return the right-hand side value if the left-hand side value is null or undefined. Otherwise, it returns the left-hand side value.
1 2 3 4 5 6 7 8
x ?? y // return x if x is not null or undefined, otherwise return y
|| returns the first truthy value among its operands, if all operands are falsy, it returns the last operand.
?? returns the first non-null and non-undefined value among its operands, if all operands are null or undefined, it returns the last operand.
Short-circuiting evaluation.
Same as ||, ?? also supports short-circuiting evaluation. If the left-hand side value is not null or undefined, the right-hand side value will not be evaluated.
This one works fine when promise is resolved. but if the promise is rejected, the test will wait for a maximum of 5 seconds timeout, and then fail. while others will fail immediately.
Posted onEdited onInjest Symbols count in article: 576Reading time ≈2 mins.
In this post, I will show you how to set up a Jest project from scratch. We won’t use any front-end frameworks like React, Angular, or Vue, just a simple vanilla JavaScript project.
CommonJs
Step 1: Create a new project
Run the following command to init a new project directory, it will simply create a package.json file in the current directory.
1
npm init -y # with -y, you don't need to answer the questions
Step 2: Install Jest
Run the following command to install Jest as a dev dependency.
1
npm install --save-dev jest
Step 3: Create a javascript file
We’ll first focus on CommonJs, create a new file named sum.js in the root directory of your project, and add the following code:
1 2 3 4
functionsum(a, b) { return a + b; } module.exports = sum;
Step 4: Create a test file
Create a new file named sum.test.js in the root directory of your project, and add the following code:
Jest encountered an unexpected token SyntaxError: Cannot use import statement outside a module
This is because you are trying to use ESModule syntax in a CommonJs environment, to fix this, you can update your file name to sum.test.mjs or you need to add the following line to the package.json file:
describe('local storage should work', () => { it('should set and get item', () => { const item = { name: 'John Doe', age: 30 }; saveItem(item); const storedItem = getItem('item'); expect(storedItem).toEqual(item); }); });
When you run this test with Jest
1 2
# first, navigate to the directory where the test file is located. jest storage-utils.spec.ts
Everything works fine, but localStorage is only available in browser environment, and you didn’t mock it, why?
This is because Jest now use jsdom as the default environment, and jsdom has implemented localStorage and sessionStorage APIs, so you don’t need to mock them anymore.
To test this, you can find the jest.config.js file in the root directory of your project, and add the following line to the testEnvironment property:
1 2 3 4 5
module.exports = { preset: 'jest-preset-angular', setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'], testEnvironment: 'node', // <-- change this to 'node' };
Then run the test again, you will see the test failed because localStorage is not available in the node environment, and you will get the following error:
1 2
localStorage is not defined ReferenceError: localStorage is not defined
Use jsdom by in test file
Suppose you global jest config is node(in file jest.config.js under project root), but you want to use jsdom in some test cases, you can use the following code in the test file, add @jest-environment jsdom at the top of the file.(Don’t use // comment, it will not work)
Posted onEdited onInhtml Symbols count in article: 209Reading time ≈1 mins.
Introduction
noscript is used in following senarios:
When the browser does not support JavaScript.
When the browser has disabled JavaScript.
How to disable JavaScript in Chrome
Open your page with Chrome.
Press F12 to open the developer tools.
Click on the three dots on the top right corner.(Or press Ctrl + Shift + P)
Type disable JavaScript in the search bar.
Click on the Disable JavaScript option.
When JavaScript was disabled, there will be a warning sign on Source tab. mouse hove on that warning sign, it will show the message JavaScript is disabled.
Example
The following code will print Hello, world! in the console if JavaScript is enabled. If JavaScript is disabled, the message This page requires JavaScript. will be displayed.
As I know, currently, React framework will generate a noscript tag in the body tag when you create your project with create-react-app.
But Angular does not have a noscript tag in the body tag. there is no browser does not support JavaScript or disable JavaScript, so it is not necessary to add a noscript tag in the body tag.
You can import the default export of a module using the following syntax:
1 2 3 4
// math.mjs exportdefaultfunctionadd(a, b) { return a + b; }
You can use any name here, not limited to add. But you can only have one default export per module.
1 2
// main.mjs import add from'./math.mjs';
Namespace imports
You can also import all exports from a module using the following syntax:
1 2 3 4 5 6 7 8
// math.mjs exportfunctionadd(a, b) { return a + b; }
exportfunctionsubtract(a, b) { return a - b; }
1 2
// main.mjs import * as math from'./math.mjs';
Side effects imports
You can also import a module for its side effects only, without importing any bindings. This is useful when you just want to run the code in the module, but don’t need to import any of its bindings.
1
import'./math.mjs';
This is very common in Angular code, especially with Module Federation, where you import a module for its side effects only.
main.ts use side effect import here which will run all global code in bootstrap.ts but not import any bindings. (Note, the following code is dynamic import, not static import)
When you run main.mjs, you will see only one random number printed in the console, which means the math module is only executed once.
1 2 3
0.2534933886729216 3 1
Dynamic import
Introduction
import() is dynamic import, it returns a promise. The import() syntax, commonly called dynamic import, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.
import() can be used in non-module environment, such as in a .js file or script tag without type="module".
1 2 3 4
// test.js, you don't need test.mjs here. import("chat-box").then(module => { module.load(); });
1 2 3 4 5 6
<!-- You don't need type="module" in script tag--> <script> import("chat-box").then(module => { module.load(); }); </script>
But static import can’t be used in non-module environment, you will got Error: SyntaxError: Cannot use import statement outside a module, to make static import work, you must use file end with .mjs or add type="module" in script tag.
1 2
import {load} from"./chat-box.mjs"; load();
1 2 3 4 5
<!-- You need type="module" in script tag--> <scripttype="module"> import {load} from"./chat-box.mjs"; load(); </script>
pass by reference
There is no real pass by reference in JavaScript like in C/C++ language, but you can use import to achieve similar effect.
First, create a module module.mjs, in this file, we export an object person.
Create another module module1.mjs, in this file, we import person from module.mjs and change the age to 40.
1 2 3
// module1.mjs import { person } from'./module.mjs'; person.age = 40;
Finally, import module1.mjs and module.mjs in main.mjs, and print the person object, you will found the age is 40 now.
1 2 3 4 5
// main.mjs import'./module1.mjs'; // This will execute the code in module1.mjs import { person } from'./module.mjs';
console.log(person);
输出如下:
1
{ name: 'zdd', age: 40 }
import.meta.url
import.meta.url The full URL to the module, includes query parameters and/or hash (following the ? or #). In browsers, this is either the URL from which the script was obtained (for external scripts), or the URL of the containing document (for inline scripts). In Node.js, this is the file path (including the file:// protocol).
In Node.js, import.meta.url is the file path of the current module. It is similar to __filename in CommonJS modules.
This is server.ts file generated by angular SSR, you can see import.meta.url is used to get the current file path.
// The Express app is exported so that it can be used by serverless Functions. exportfunctionapp(): express.Express { const server = express(); const serverDistFolder = dirname(fileURLToPath(import.meta.url)); const browserDistFolder = resolve(serverDistFolder, '../browser'); const indexHtml = join(serverDistFolder, 'index.server.html'); }