Skip to content

dev-sabbir/clean-code-javascript

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

āφāϏāϞ āϰāĻŋāĻĒā§‹āϜāĻŋāϟāϰāĻŋ: ryanmcdermott/clean-code-javascript

clean-code-javascript

āϏ⧂āϚāĻŋāĻĒāĻ¤ā§āϰ

  1. āĻ­ā§‚āĻŽāĻŋāĻ•āĻž
  2. āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞāϏ
  3. āĻĢāĻžāĻ‚āĻļāύāϏ
  4. āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ
  5. āĻ•ā§āϞāĻžāϏ
  6. āϏāϞāĻŋāĻĄ(SOLID)
  7. āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚
  8. āĻ•āύāĻ•āĻžāϰ⧇āĻ¨ā§āϏāĻŋ
  9. āĻāϰāϰ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚
  10. āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚
  11. āĻ•āĻŽā§‡āĻ¨ā§āϟāϏ
  12. āĻ…āύ⧁āĻŦāĻžāĻĻ

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž

Humorous image of software quality estimation as a count of how many expletives you shout when reading code

āĻāĻ–āĻžāύ⧇ āϰāĻŦāĻžāĻ°ā§āϟ āϏāĻŋ. āĻŽāĻžāĻ°ā§āϟāĻŋāύ āĻāϰ Clean Code āĻŦāĻ‡ā§Ÿā§‡ āĻŦāĻ°ā§āύāĻŋāϤ āϏāĻĢāϟāĻ“ā§Ÿā§āϝāĻžāϰ āχāĻžā§āϜāĻŋāύāĻŋ⧟āĻžāϰāĻŋāĻ‚ āĻāϰ āύ⧀āϤāĻŋāϗ⧁āϞ⧋āϕ⧇ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻāϰ āϜāĻ¨ā§āϝ āĻ•āĻŋāϛ⧁āϟāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤ āĻāϟāĻž āϕ⧋āύ āĻ¸ā§āϟāĻžāχāϞ āĻ—āĻžāχāĻĄ āύāĻžāĨ¤ āĻāϟāĻž āĻšāϞ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϏ⧁āĻĒāĻžāĻ ā§āϝ, āĻĒ⧁āύāĻŦā§āϝāĻŦāĻšāĻžāϰāϝ⧋āĻ—ā§āϝ, āϰāĻŋāĻĢā§āϝāĻžāĻ•ā§āϟāϰāϝ⧋āĻ—ā§āϝ āϏāĻĢāϟāĻ“ā§Ÿā§āϝāĻžāϰ āϤ⧈āϰāĻŋ āĻ•āϰāĻžāϰ āĻ—āĻžāχāĻĄāĨ¤

āĻŦā§āϝāĻžāĻĒāĻžāϰāϟāĻž āĻāĻŽāύ āύāĻž āϝ⧇ āĻāĻ–āĻžāύ⧇ āĻŦāĻ°ā§āύāĻŋāϤ āϏāĻŦ āύāĻŋ⧟āĻŽ āĻ•āĻ ā§‹āϰāĻ­āĻžāĻŦ⧇ āĻŽā§‡āύ⧇ āϚāϞāϤ⧇ āĻšāĻŦ⧇, āĻāĻŽāύāĻ•āĻŋ āĻāĻ–āĻžāύ⧇ āĻŦāĻ°ā§āύāĻŋāϤ āϖ⧁āĻŦ āĻ•āĻŽ āύāĻŋ⧟āĻŽā§‡āϰ āϏāĻžāĻĨ⧇ āϏāĻŦāĻžāχ āĻāĻ•āĻŽāϤāĨ¤ āĻāϗ⧁āϞ⧋ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āĻŦā§āϝāĻžāϤāĻŋāϤ āĻ•āĻŋāϛ⧁āχ āύāĻžāĨ¤ āϤāĻŦ⧇ āĻāϗ⧁āϞ⧋ Clean Code āĻŦāĻ‡ā§Ÿā§‡āϰ āϞ⧇āĻ–āĻ•āĻĻ⧇āϰ āĻŦāĻšā§ āĻŦāĻ›āϰ⧇āϰ āϏāĻŽāĻˇā§āϟāĻŋāĻ—āϤ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āĻĨ⧇āϕ⧇ āĻŦāĻŋāϧāĻŋāĻŦāĻĻā§āϧ āĻ•āϰāĻžāĨ¤

āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻĢāϟāĻ“ā§ŸāĻžāϰ āχāĻžā§āϜāĻŋāύāĻŋ⧟āĻžāϰāĻŋāĻ‚ āĻļāĻŋāĻ˛ā§āĻĒ⧇āϰ āĻŦ⧟āϏ ā§Ģā§Ļ āĻŦāĻ›āϰ⧇āϰ āĻ•āĻŋāϛ⧁ āĻŦ⧇āĻļāĻŋ āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻāĻ–āύāĻ“ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁ āĻļāĻŋāĻ–āĻ›āĻŋāĨ¤ āϝāĻ–āύ āϏāĻĢāϟāĻ“ā§ŸāĻžāϰ āφāĻ°ā§āĻ•āĻŋāĻŸā§‡āĻ•āϚāĻžāϰ āĻ¸ā§āĻĨāĻžāĻĒāĻ¤ā§āϝāĻ•āϞāĻžāϰ āĻŽāϤ āĻĒ⧁āϰāύ⧋ āĻšāĻŦ⧇, āϤāĻ–āύ āĻšā§ŸāϤ āφāĻŽāϰāĻž āĻŽā§‡āύ⧇ āϚāϞāĻžāϰ āϜāĻ¨ā§āϝ āĻ•āĻŋāϛ⧁ āĻ•āĻ ā§‹āϰ āύāĻŋ⧟āĻŽ āĻĒāĻžāĻŦāĨ¤ āϏ⧇āĻĻāĻŋāύ⧇āϰ āφāĻ— āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āφāĻŽāϰāĻž āϝ⧇ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϕ⧋āĻĄ āϤ⧈āϰāĻŋ āĻ•āϰāĻ›āĻŋ āϤāĻžāϰ āĻŽāĻžāύ āϝāĻžāϚāĻžāχ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻāχ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻžāϟāĻŋāϕ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž āĻļ⧇āώ āĻ•āϰāĻžāϰ āφāϗ⧇ āĻāĻ•āϟāĻž āĻ•āĻĨāĻž, āĻāχ āύāĻŋ⧟āĻŽ āϗ⧁āϞ⧋ āϜāĻžāύāϞ⧇āχ āϤ⧁āĻŽāĻŋ āφāϗ⧇āϰ āĻĨ⧇āϕ⧇ āĻ­āĻžāϞ⧋ āϏāĻĢāϟāĻ“ā§Ÿā§āϝāĻžāϰ āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ āĻšā§Ÿā§‡ āϝāĻžāĻŦ⧇ āύāĻž āĻāĻŦāĻ‚ āĻāϗ⧁āϞ⧋ āĻ…āύ⧇āĻ• āĻŦāĻ›āϰ āϧāϰ⧇ āĻŽā§‡āύ⧇ āϚāϞāĻž āĻŽāĻžāύ⧇ āĻāχ āύāĻž āϝ⧇ āϤ⧁āĻŽāĻŋ āφāϰ āϭ⧁āϞ āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤ āĻŽāĻžāϟāĻŋāϰ āĻĻāϞāĻž āĻĨ⧇āϕ⧇ āϝ⧇āĻŽāύ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āφāĻ•ā§ƒāϤāĻŋ āϤ⧈āϰāĻŋ āĻšā§Ÿ, āϤ⧇āĻŽāύāĻŋ āĻĒā§āϰāϤāĻŋāϟāĻž āϕ⧋āĻĄ āĻļ⧁āϰ⧁ āĻšā§Ÿ āĻĒā§āϰāĻĨāĻŽ āĻ–āϏ⧜āĻž āĻĨ⧇āϕ⧇āĨ¤ āφāĻŽāϰāĻž āϝāĻ–āύ āϏāĻŦāĻļ⧇āώ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻšāĻ•āĻ°ā§āĻŽā§€āĻĻ⧇āϰ āϏāĻžāĻĨ⧇ āϕ⧋āĻĄ āϰāĻŋāĻ­āĻŋāĻ“ āĻ•āϰāϤ⧇ āĻŦāϏāĻŋ āϤāĻ–āύ āφāĻŽāĻžāĻĻ⧇āϰ āϕ⧋āĻĄā§‡āϰ āĻ…āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖāϤāĻžāϗ⧁āϞ⧋āϕ⧇ āĻšā§‡āρāϛ⧇ āĻĢ⧇āϞ⧇ āĻĻāĻŋāχāĨ¤ āĻĒā§āϰāĻĨāĻŽ āĻ–āϏ⧜āĻžāϤ⧇ āϭ⧁āϞ āĻĨāĻžāĻ•āĻŦ⧇āχāĨ¤ āĻāϜāĻ¨ā§āϝ āύāĻŋāĻœā§‡āϕ⧇ āĻļāĻžāĻ¸ā§āϤāĻŋ āĻĻāĻŋāĻ“ āύāĻž, āĻŦāϰāĻ‚ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āĻā§‡ā§œā§‡āĻŽā§āϛ⧇ āĻ āĻŋāĻ• āĻ•āϰāĨ¤

āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞāϏ

āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āĻāϰ āύāĻžāĻŽ āĻ…āĻ°ā§āĻĨāĻŦāĻš āĻšāϤ⧇ āĻšāĻŦ⧇

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const yyyymmdstr = moment().format("YYYY/MM/DD");

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const currentDate = moment().format("YYYY/MM/DD");

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻāĻ•āχ āϧāϰāϪ⧇āϰ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āύāĻžāĻŽāĻ•āϰāύ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āχ āϧāϰāϪ⧇āϰ āĻļāĻŦā§āĻĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

getUserInfo();
getClientData();
getCustomerRecord();

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

getUser();

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϖ⧁āρāϜāϤ⧇ āϏ⧁āĻŦāĻŋāϧāĻž āĻšā§Ÿ āĻāĻŽāύ āύāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āφāĻŽāϰāĻž āφāĻŽāĻžāĻĻ⧇āϰ āĻĄā§‡āϭ⧇āϞāĻĒāĻžāϰ āĻœā§€āĻŦāύ⧇ āϝāϤ āϕ⧋āĻĄ āϞāĻŋāĻ–āĻŦ, āĻĒ⧜āϤ⧇ āĻšāĻŦ⧇ āϤāĻžāϰ āĻĨ⧇āϕ⧇ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋāĨ¤ āĻāĻ•āĻžāϰāϪ⧇ āϏ⧁āĻĒāĻžāĻ ā§āϝ āĻāĻŦāĻ‚ āϏāĻšāĻœā§‡ āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžā§Ÿ āĻāĻŽāύ āϕ⧋āĻĄ āϞāĻŋāĻ–āĻž āϖ⧁āĻŦāχ āϗ⧁āϰ⧁āĻ¤ā§āϤāĻĒ⧁āĻ°ā§āύāĨ¤ āφāĻŽāϰāĻž āϝāĻĻāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āϞāĻŋāĻ–āĻž āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻŦ⧁āĻāĻžāϰ āϜāĻ¨ā§āϝ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āύāĻžāĻŽ āϝāĻĨ⧇āĻˇā§āϟ āĻ…āĻ°ā§āĻĨāĻŦāĻš āύāĻž āĻ•āϰāĻŋ, āφāĻŽāĻžāĻĻ⧇āϰ āĻĒāĻžāĻ āĻ•āĻĻ⧇āϰ āĻ•āĻˇā§āϟ āĻŦāĻžā§œāĻŦ⧇ āĻŦāχ āĻ•āĻŽāĻŦ⧇ āύāĻžāĨ¤ āϝ⧇āϏāĻ•āϞ āĻ§ā§āϰ⧁āĻŦāĻ• āĻāĻŦāĻ‚ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āύāĻžāĻŽāĻ•āϰāύ āĻ•āϰāĻž āĻšā§Ÿ āύāĻŋ āϏ⧇āϗ⧁āϞ⧋ āϚāĻŋāĻšā§āύāĻŋāϤ āĻ•āϰāϤ⧇ buddy.js āĻāĻŦāĻ‚ ESLint āĻāϰ āĻŽāϤ āϟ⧁āϞāϗ⧁āϞ⧋ āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

// What the heck is 86400000 for?
setTimeout(blastOff, 86400000);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

// Declare them as capitalized named constants.
const MILLISECONDS_IN_A_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_IN_A_DAY);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āύāĻžāĻŽ āĻĻ⧇āϖ⧇āχ āϝ⧇āύ āĻŦ⧁āĻāĻž āϝāĻžā§Ÿ āĻāχāϰāĻ•āĻŽāĻ­āĻžāĻŦ⧇ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āĻāϰ āύāĻžāĻŽāĻ•āϰāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const address = "One Infinite Loop, Cupertino 95014";
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
  address.match(cityZipCodeRegex)[1],
  address.match(cityZipCodeRegex)[2]
);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const address = "One Infinite Loop, Cupertino 95014";
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻŽā§‡āĻ¨ā§āϟāĻžāϞ āĻŽā§āϝāĻžāĻĒāĻŋāĻ‚ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇

āύāĻžāχ āĻŽāĻžāĻŽāĻžāϰ āĻšā§‡ā§Ÿā§‡ āĻ•āĻžāύāĻž āĻŽāĻžāĻŽāĻž āĻ­āĻžāϞ⧋āĨ¤ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āύāĻžāĻŽāĻ•āϰāύ⧇āϰ āϏāĻŽā§Ÿ āĻāϰ āĻ–ā§‡ā§ŸāĻžāϞ āϰāĻžāĻ–āϤ⧇ āĻšāĻŦ⧇ āύāĻžāĻŽ āĻĨ⧇āϕ⧇ āϝ⧇āύ āĻāϰ āĻ•āĻžāϜ āĻŦ⧁āĻāĻž āϝāĻžā§ŸāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(l => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  // Wait, what is `l` for again?
  dispatch(l);
});

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(location => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  dispatch(location);
});

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āĻĒā§āĻ°ā§Ÿā§‹āϜāĻ¨ā§€ā§Ÿ āĻ•āĻ¨ā§āĻŸā§‡āĻ•ā§āϏāϟ āϝ⧋āĻ— āĻ•āϰāĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχ

āĻ•ā§āϞāĻžāϏ/āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āύāĻžāĻŽ āĻĨ⧇āϕ⧇ āϕ⧋āύ āϤāĻĨā§āϝ āϜāĻžāύāĻž āϗ⧇āϞ⧇ āϏ⧇āχ āϤāĻĨā§āϝ āφāĻŦāĻžāϰ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āύāĻžāĻŽā§‡āϰ āĻŽāĻ§ā§āϝ⧇ āϰāĻžāĻ–āĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const Car = {
  carMake: "Honda",
  carModel: "Accord",
  carColor: "Blue"
};

function paintCar(car) {
  car.carColor = "Red";
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const Car = {
  make: "Honda",
  model: "Accord",
  color: "Blue"
};

function paintCar(car) {
  car.color = "Red";
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻļāĻ°ā§āϟ āϏāĻžāĻ°ā§āĻ•āĻŋāϟāĻŋāĻ‚/āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύāĻžāϞ āĻ¸ā§āĻŸā§‡āϟāĻŽā§‡āĻ¨ā§āϟ āĻĨ⧇āϕ⧇ āĻĄāĻŋāĻĢāĻ¨ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻ­āĻžāϞ⧋āĨ¤

āĻļāĻ°ā§āϟ āϏāĻžāĻ°ā§āĻ•āĻŋāϟāĻŋāĻ‚ āĻĨ⧇āϕ⧇ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āĻĒāϰāĻŋāĻšā§āĻ›āĻ¨ā§āύāĨ¤ āϤāĻŦ⧇ āĻāϟāĻž āĻŽāĻžāĻĨāĻžā§Ÿ āϰāĻžāĻ–āϤ⧇ āĻšāĻŦ⧇ āϝ⧇, āϝāĻĻāĻŋ āφāĻŽāϰāĻž āĻĢāĻžāĻ‚āĻļāύ⧇ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŋ āϤāĻŦ⧇ āĻ…āϏāĻ™ā§āĻ—āĻžā§ŸāĻŋāϤ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āχ āĻļ⧁āϧ⧁ āĻŽāĻžāĻ¤ā§āϰ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāĻŦ⧇āĨ¤ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ falsy āĻ­ā§āϝāĻžāϞ⧁, āϝ⧇āĻŽāύāσ '', "", false, null, 0, āĻāĻŦāĻ‚ NaN, āĻāϗ⧁āϞ⧋āϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤ⧇ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ­ā§āϝāĻžāϞ⧁ āĻŦāϏāĻŦ⧇ āύāĻžāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function createMicrobrewery(name) {
  const breweryName = name || "Hipster Brew Co.";
  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function createMicrobrewery(name = "Hipster Brew Co.") {
  // ...
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĢāĻžāĻ‚āĻļāύāϏ

āĻĢāĻžāĻ‚āĻļāύ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟāϏ (⧍āϟāĻžāϰ āĻŦ⧇āĻļāĻŋ āύ⧟, ā§§ āϟāĻž āĻšāϞ⧇ āĻ­āĻžāϞ āĻšā§Ÿ)

āĻĢāĻžāĻ‚āĻļāύ āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚ āϏāĻšāϜ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ, āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āϕ⧇ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧ āĻ•āϰāĻž āϖ⧁āĻŦāχ āϗ⧁āϰ⧁āĻ¤ā§āϤāĻĒ⧁āĻ°ā§āύ āĨ¤ āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ ā§Š āĻāϰ āĻ…āϧāĻŋāĻ• āĻšāϞ⧇, āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ āϏāĻŽāĻžāĻŦ⧇āĻļ⧇āϰ āĻ•āĻžāϰāϪ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻŸā§‡āĻ¸ā§āϟ āϕ⧇āϏ⧇āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻŦā§‡ā§œā§‡ āϝāĻžā§ŸāĨ¤

āĻāĻ•āĻĻāĻŽāχ āĻ…āĻĒāĻžāϰāĻ— āĻšāϞ⧇ ā§Š āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āωāϚāĻŋāϤāĨ¤ āϤāĻŦ⧇ āφāĻĻāĻ°ā§āĻļ āĻšāϞ ⧍ āĻŦāĻž āϤāĻžāϰ āĻ•āĻŽāĨ¤ āĻāϰ āĻĨ⧇āϕ⧇ āĻŦ⧇āĻļāĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻšāϞ⧇ āϤāĻžāĻĻ⧇āϰāϕ⧇ āĻāĻ•āϟāĻž āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āĻ¤ā§āϰ⧀āĻ•āϰāϪ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻāϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻ•āĻŽāĻŋā§Ÿā§‡ āφāύāϤ⧇ āĻšāĻŦ⧇āĨ¤

āϝ⧇āĻšā§‡āϤ⧁ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āϗ⧇āϞ⧇ āĻ•ā§āϞāĻžāϏ āĻŦ⧟āϞāĻžāϰāĻĒā§āϞ⧇āϟ āϞāĻžāϗ⧇ āύāĻž, āϤāĻžāχ āϝāĻĻāĻŋ āϤ⧋āĻŽāĻžāϰ āĻ…āύ⧇āĻ•āϗ⧁āϞ⧋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āĻšā§Ÿ āϤāĻŦ⧇ āϤ⧁āĻŽāĻŋ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĨ¤

āĻāĻ•āϟāĻž āĻĢāĻžāĻ‚āĻļāύ⧇ āĻ•āĻŋ āĻ•āĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āφāϏāϞ⧇ āϝāĻžāĻšā§āϛ⧇ āϤāĻž āĻŦ⧁āĻāĻžāύ⧋āϰ āϜāĻ¨ā§āϝ ES2015/ES6 āĻāϰ destructuring syntax āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĨ¤ āĻāϟāĻžāϰ āĻ•āĻŋāϛ⧁ āϏ⧁āĻŦāĻŋāϧāĻž āφāϛ⧇,

  1. āϝāĻ–āύ āϕ⧇āω āĻĢāĻžāĻ‚āĻļāύ āϏāĻŋāĻ—āύ⧇āϚāĻžāϰ āĻĻ⧇āĻ–āĻŦ⧇ āϤāĻ–āύāĻŋ āĻŦ⧁āĻā§‡ āĻĢ⧇āϞāĻŦ⧇ āĻ•āĻŋ āĻ•āĻŋ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻĻā§‡ā§ŸāĻž āĻšāĻšā§āϛ⧇ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻŽāĻ§ā§āϝ⧇āĨ¤
  2. Destructring āĻ•āϰāϞ⧇, āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āĻšāĻŋāϏ⧇āĻŦ⧇ āϝ⧇ āĻĒā§āϰāĻŋāĻŽāĻŋāϟāĻŋāĻ­ āĻ­ā§āϝāĻžāϞ⧁ āĻĻā§‡ā§ŸāĻž āĻšā§Ÿā§‡āϛ⧇ āϏ⧇āϗ⧁āϞ⧋ āĻ•ā§āϞ⧋āύ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤ āϝāĻž āĻ•āĻŋāύāĻž āφāĻŽāĻžāĻĻ⧇āϰ āϕ⧇ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻĒā§āϰāϤāĻŋāϰ⧋āϧ āĻ•āϰāϤ⧇ āϏāĻšāĻžā§ŸāϤāĻž āĻ•āϰ⧇āĨ¤ āϤāĻŦ⧇ āĻŽāĻžāĻĨāĻžā§Ÿ āϰāĻžāĻ–āϤ⧇ āĻšāĻŦ⧇, āϝāĻĻāĻŋ āĻāϰ⧇ āĻŦāĻž āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ destructure āĻ•āϰāĻž āĻšā§Ÿ, āϏ⧇āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻāϰāĻž āĻ•ā§āϞ⧋āύ āĻšā§Ÿ āύāĻžāĨ¤
  3. āĻ…āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āϞ⧀āύāϟāĻžāϰ āφāĻŽāĻžāĻĻ⧇āϰ āĻšā§‡āĻ˛ā§āĻĒ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ Destructure āύāĻž āĻ•āϰāϞ⧇ āĻšā§ŸāϤ āĻāϟāĻž āϏāĻŽā§āĻ­āĻŦ āĻšāϤ āύāĻžāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function createMenu(title, body, buttonText, cancellable) {
  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function createMenu({ title, body, buttonText, cancellable }) {
  // ...
}

createMenu({
  title: "Foo",
  body: "Bar",
  buttonText: "Baz",
  cancellable: true
});

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĒā§āϰāϤāĻŋāϟāĻž āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻļ⧁āϧ⧁ āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ āĻ•āĻžāϜ āĻ•āϰāĻž āωāϚāĻŋāϤ

āϏāĻĢāϟāĻ“ā§Ÿā§āϝāĻžāϰ āχāĻžā§āϜāĻŋāύāĻŋ⧟āĻžāϰāĻŋāĻ‚ āĻ āĻāĻ–āύ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻāϟāĻžāχ āϏāĻŦ āĻĨ⧇āϕ⧇ āϗ⧁āϰ⧁āĻ¤ā§āϤāĻĒ⧁āĻ°ā§āύ āύ⧀āϤāĻŋāĨ¤ āϝ⧇āϏāĻŦ āĻĢāĻžāĻ‚āĻļāύ āϝāĻĻāĻŋ āĻāϕ⧇āϰ āĻ…āϧāĻŋāĻ• āĻ•āĻžāϜ āĻ•āϰ⧇, āϏ⧇āϏāĻŦ āĻĢāĻžāĻ‚āĻļāύ āĻŸā§‡āĻ¸ā§āϟ āĻ•āϰāĻž, āĻ…āĻ¨ā§āϝ āϝāĻžā§ŸāĻ—āĻžā§Ÿ āĻĒ⧁āύāĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻ•āĻ āĻŋāύ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āϝāĻĻāĻŋ āϕ⧇āĻŦāϞ āĻāĻ•āϟāĻŋ āĻ•āĻžāϜ āĻ•āϰ⧇ āϤāĻŦ⧇ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āϏ⧁āĻĒāĻžāĻ ā§āϝ āĻāĻŦāĻ‚ āϏāĻšāĻœā§‡ āĻĒ⧁āύāϰāĻžā§Ÿ āϞ⧇āĻ–āĻž āϝāĻžāĻŦ⧇āĨ¤ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āĻāχ āĻ—āĻžāχāĻĄā§‡āϰ āφāϰ āĻ•āĻŋāϛ⧁ āύāĻž āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇ āĻļ⧁āϧ⧁ āĻāχ āύāĻŋ⧟āĻŽāϟāĻŋ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ, āϤāĻžāĻšāϞ⧇āχ āϤ⧁āĻŽāĻŋ āĻ…āĻ¨ā§āϝ āĻĄā§‡āϭ⧇āϞāĻĒ⧇āϰ āĻĨ⧇āϕ⧇ āĻ…āύ⧇āĻ• āĻāĻ—āĻŋā§Ÿā§‡ āϝāĻžāĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function emailClients(clients) {
  clients.forEach(client => {
    const clientRecord = database.lookup(client);
    if (clientRecord.isActive()) {
      email(client);
    }
  });
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function emailActiveClients(clients) {
  clients.filter(isActiveClient).forEach(email);
}

function isActiveClient(client) {
  const clientRecord = database.lookup(client);
  return clientRecord.isActive();
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āύāĻžāĻŽā§‡āχ āĻŦāϞāĻž āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇ āϏ⧇āϟāĻŋ āĻ•āĻŋ āĻ•āϰ⧇

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function addToDate(date, month) {
  // ...
}

const date = new Date();

// It's hard to tell from the function name what is added
addToDate(date, 1);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function addMonthToDate(month, date) {
  // ...
}

const date = new Date();
addMonthToDate(1, date);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĢāĻžāĻ‚āĻļāύ⧇ āĻļ⧁āϧ⧁ āĻāĻ•āϧāĻžāĻĒ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰāĻŦ⧇

āϤ⧋āĻŽāĻžāϰ āĻĢāĻžāĻ‚āĻļāύ⧇ āĻāϕ⧇āϰ āĻ…āϧāĻŋāĻ• āϧāĻžāĻĒ⧇ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āĻĨāĻžāĻ•āĻž āĻŽāĻžāύ⧇āχ āϤ⧋āĻŽāĻžāϰ āĻĢāĻžāĻ‚āĻļāύ āĻāϕ⧇āϰ āĻ…āϧāĻŋāĻ• āĻ•āĻžāϜ āĻ•āϰāϛ⧇āĨ¤ āĻāϕ⧇ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āϛ⧋āϟāϛ⧋āϟ āĻ­āĻžāϗ⧇ āĻŦāĻŋāĻ­āĻ•ā§āϤ āĻ•āϰāϞ⧇ āĻĒ⧁āύāϰāĻžā§Ÿ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž , āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āϰāĻž āϏāĻšāϜ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function parseBetterJSAlternative(code) {
  const REGEXES = [
    // ...
  ];

  const statements = code.split(" ");
  const tokens = [];
  REGEXES.forEach(REGEX => {
    statements.forEach(statement => {
      // ...
    });
  });

  const ast = [];
  tokens.forEach(token => {
    // lex...
  });

  ast.forEach(node => {
    // parse...
  });
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function parseBetterJSAlternative(code) {
  const tokens = tokenize(code);
  const syntaxTree = parse(tokens);
  syntaxTree.forEach(node => {
    // parse...
  });
}

function tokenize(code) {
  const REGEXES = [
    // ...
  ];

  const statements = code.split(" ");
  const tokens = [];
  REGEXES.forEach(REGEX => {
    statements.forEach(statement => {
      tokens.push(/* ... */);
    });
  });

  return tokens;
}

function parse(tokens) {
  const syntaxTree = [];
  tokens.forEach(token => {
    syntaxTree.push(/* ... */);
  });

  return syntaxTree;
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āĻĨāĻžāĻ•āĻž āϝāĻžāĻŦ⧇ āύāĻž

āϤ⧋āĻŽāĻžāϰ āϏāĻ°ā§āĻŦā§‹āĻšā§āϚ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻŦ⧇ āϝ⧇āύ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āύāĻž āĻĨāĻžāϕ⧇āĨ¤ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āĻĨāĻžāĻ•āĻž āĻŽāĻžāύ⧇āχ, āĻ•āĻ–āύ⧋ āϕ⧋āύ āĻāĻ•āϟāĻžāϰ āϞāϜāĻŋāĻ• āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϞāĻžāĻ—āϞ⧇ āϤ⧋āĻŽāĻžāϰ āϏāĻŦāϗ⧁āϞ⧋ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄā§‡ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϞāĻžāĻ—āĻŦ⧇āĨ¤

āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰ āϤ⧁āĻŽāĻŋ āĻāĻ•āϟāĻž āϰ⧇āĻ¸ā§āϟ⧁āϰ⧇āĻ¨ā§āϟ āĻ āφāϛ⧋ āĻāĻŦāĻ‚ āϤ⧋āĻŽāĻžāϰ āĻ•āĻžāϜ āĻšāĻšā§āϛ⧇ āϰ⧇āĻ¸ā§āϟ⧁āϰ⧇āĻ¨ā§āϟ āĻāϰ āĻ¸ā§āĻŸā§‹āϰ⧇ āĻ•āĻŋ āĻ•āĻŋ āφāϛ⧇ āϏ⧇āϗ⧁āϞ⧋āϰ āĻ–āĻŦāϰ āϰāĻžāĻ–āĻžāĨ¤ āĻŽāĻžāύ⧇ āĻšāϞ āϰ⧇āĻ¸ā§āϟ⧁āϰ⧇āĻ¨ā§āĻŸā§‡ āĻ•āϤāϟ⧁āϕ⧁ āϟāĻŽāĻžāĻŸā§‹, āĻĒ⧇āρ⧟āĻžāϜ, āĻšāϞ⧁āĻĻ, āĻŽāĻļāϞāĻž āφāϛ⧇ āϏ⧇āϗ⧁āϞ⧋āϰ āĻšāĻŋāϏāĻžāĻŦ āϰāĻžāĻ–āĻžāĨ¤ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āĻ…āύ⧇āĻ•āϗ⧁āϞ⧋ āϝāĻžā§ŸāĻ—āĻžā§Ÿ āĻāĻĻ⧇āϰ āĻšāĻŋāϏāĻžāĻŦ āϰāĻžāĻ–, āϕ⧋āύ āĻāĻ•āϟāĻžāϰ āĻšāĻŋāĻļāĻžāĻŦ āĻ•āĻŽāϞ⧇ āĻŦāĻž āĻŦāĻžā§œāϞ⧇ āϤ⧋āĻŽāĻžāϰ āϏāĻŦ āϞāĻŋāĻ¸ā§āĻŸā§‡ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϞāĻžāĻ—āĻŦ⧇āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āĻāĻ•āϟāĻž āϞāĻŋāĻ¸ā§āĻŸā§‡ āĻāĻĻ⧇āϰ āĻšāĻŋāϏāĻžāĻŦ āϰāĻžāĻ–āϤ⧇ āϤāĻžāĻšāϞ⧇ āĻāĻ•āϟāĻž āϞāĻŋāĻ¸ā§āĻŸā§‡ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϞ⧇āχ āĻšāϤāĨ¤

āĻŽāĻžāĻā§‡ āĻŽāĻžāĻā§‡ āĻāĻŽāύ āĻšā§Ÿ āϝ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āϞāĻŋāĻ–āϤ⧇ āĻšā§Ÿ, āĻ•āĻžāϰāĻŖ āĻĻ⧇āĻ–āĻž āϝāĻžā§Ÿ, ⧍ āϟāĻž āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϰāĻžā§Ÿ āĻāĻ•āχ āĻ•āĻžāϜ āĻ•āϰāϛ⧇ āĻļ⧁āϧ⧁ āϏāĻžāĻŽāĻžāĻ¨ā§āϝ āĻāĻ•āϟ⧁ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āφāϛ⧇āĨ¤ āĻāχ āϏāĻžāĻŽāĻžāĻ¨ā§āϝ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ⧇āϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāĻĻ⧇āϰ ⧍ āϟāĻž āĻĢāĻžāĻ‚āĻļāύ āϞ⧇āĻ–āĻž āϞāĻžāϗ⧇āĨ¤ āĻāĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻāĻ•āϟāĻž āϏāĻŽāĻžāϧāĻžāύ āĻšāϞ, āĻāĻ•āϟāĻž āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āϤ⧈āϰāĻŋ āĻ•āϰāĻžāĨ¤

āĻāχ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύāϟāĻž āĻ āĻŋāĻ•āĻ āĻžāĻ• āĻ­āĻžāĻŦ⧇ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻž āϖ⧁āĻŦāχ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒ⧁āĻ°ā§āύāĨ¤ āĻāĻ•āĻžāϰāϪ⧇ āϤ⧋āĻŽāĻžāϰ āωāϚāĻŋāϤ āĻ•ā§āϞāĻžāϏ āĻ…āĻ§ā§āϝāĻžā§Ÿā§‡ āĻŦāĻ°ā§āύāĻŋāϤ SOLID āĻĒā§āϰāĻŋāĻ¨ā§āϏāĻŋāĻĒāĻžāϞ āĻŽā§‡āύ⧇ āϚāϞāĻžāĨ¤ āϭ⧁āϞ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āĻĨ⧇āϕ⧇āĻ“ āĻ•ā§āώāϤāĻŋāĻ•āϰ, āĻ…āϤāĻāĻŦ āϏāĻžāϧ⧁ āϏāĻžāĻŦāϧāĻžāύ! āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āϏāĻ āĻŋāĻ• āĻ­āĻžāĻŦ⧇ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ āϤāĻŦ⧇ āĻ•āϰ⧇ āĻĢ⧇āϞāĨ¤ āϤāĻž āύāĻžāĻšāϞ⧇ āĻāĻ•āϟāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āĻžāϧāĻŋāĻ• āϜāĻžā§ŸāĻ—āĻžā§Ÿ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϞāĻžāĻ—āĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function showDeveloperList(developers) {
  developers.forEach(developer => {
    const expectedSalary = developer.calculateExpectedSalary();
    const experience = developer.getExperience();
    const githubLink = developer.getGithubLink();
    const data = {
      expectedSalary,
      experience,
      githubLink
    };

    render(data);
  });
}

function showManagerList(managers) {
  managers.forEach(manager => {
    const expectedSalary = manager.calculateExpectedSalary();
    const experience = manager.getExperience();
    const portfolio = manager.getMBAProjects();
    const data = {
      expectedSalary,
      experience,
      portfolio### Function names should say what they do
    };

    render(data);
  });
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function showEmployeeList(employees) {
  employees.forEach(employee => {
    const expectedSalary = employee.calculateExpectedSalary();
    const experience = employee.getExperience();

    const data = {
      expectedSalary,
      experience
    };

    switch (employee.type) {
      case "manager":
        data.portfolio = employee.getMBAProjects();
        break;
      case "developer":
        data.githubLink = employee.getGithubLink();
        break;
    }

    render(data);
  });
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āϏ⧇āϟ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ Object.assign āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const menuConfig = {
  title: null,
  body: "Bar",
  buttonText: null,
  cancellable: true
};

function createMenu(config) {
  config.title = config.title || "Foo";
  config.body = config.body || "Bar";
  config.buttonText = config.buttonText || "Baz";
  config.cancellable =
    config.cancellable !== undefined ? config.cancellable : true;
}

createMenu(menuConfig);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const menuConfig = {
  title: "Order",
  // User did not include 'body' key
  buttonText: "Send",
  cancellable: true
};

function createMenu(config) {
  config = Object.assign(
    {
      title: "Foo",
      body: "Bar",
      buttonText: "Baz",
      cancellable: true
    },
    config
  );

  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}

createMenu(menuConfig);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϝāĻžāϰāĻžāĻŽāĻŋāϟāĻžāϰ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻĢā§āĻ˛ā§āϝāĻžāĻ— āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ⧇ āύāĻž

āĻĢā§āĻ˛ā§āϝāĻžāĻ— āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϞ⧇ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āϰāĻŋāĻ­āĻŋāĻ“ā§ŸāĻžāϰ āĻŦ⧁āĻāϤ⧇ āĻĒāĻžāϰ⧇ āϝ⧇ āĻāχ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋ āĻāĻ•āĻžāϧāĻŋāĻ• āĻ•āĻžāϜ āĻ•āϰāϛ⧇āĨ¤ āϝāĻĻāĻŋ āĻĢā§āĻ˛ā§āϝāĻžāĻ— āĻāϰ āĻ­ā§āϝāĻžāϞ⧁ āĻāϰ āωāĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄāĻĢā§āϞ⧋ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĻāĻŋāϕ⧇ āϝāĻžā§Ÿ, āϤāĻŦ⧇ āϤāĻžāĻĻ⧇āϰ āϕ⧇ āφāϞāĻžāĻĻāĻž āĻĢāĻžāĻ‚āĻļāύ⧇ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰāĻŋāϤ āĻ•āϰāĨ¤ āϤāĻžāϰāĻĒāϰ āϤ⧋āĻŽāĻžāϰ āĻĢā§āĻ˛ā§āϝāĻžāĻ— āĻāϰ āωāĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĢāĻžāĻ‚āĻļāύ āϕ⧇ āĻ•āϞ āĻ•āϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function createFile(name, temp) {
  if (temp) {
    fs.create(`./temp/${name}`);
  } else {
    fs.create(name);
  }
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function createFile(name) {
  fs.create(name);
}

function createTempFile(name) {
  createFile(`./temp/${name}`);
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇ (āĻĒāĻžāĻ°ā§āϟ-ā§§)

āϝāĻ–āύ āĻāĻ•āϟāĻž āĻĢāĻžāĻ‚āĻļāύ āĻ­ā§āϝāĻžāϞ⧁ āφāĻĻāĻžāύāĻĒā§āϰāĻĻāĻžāύ āĻ›āĻžā§œāĻž āĻ…āĻ¨ā§āϝ āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇ āϤāĻ–āύāχ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āϤ⧈āϰāĻŋ āĻšā§ŸāĨ¤ āĻĢāĻžāχāϞ⧇ āϰāĻžāχāϟ āĻ•āϰāĻž, āĻ—ā§āϞ⧋āĻŦāĻžāϞ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻž āĻāϗ⧁āϞ⧋ āĻšāϞ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻāϰ āωāĻĻāĻžāĻšāϰāĻŖāĨ¤

āĻŽāĻžāĻā§‡ āĻŽāĻžāĻā§‡ āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻāϰ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āĻšā§Ÿ, āϝ⧇āĻŽāύāσ āĻĢāĻžāχāϞ⧇ āϰāĻžāχāϟ āĻ•āϰāĻžāĨ¤ āϏ⧇āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āφāĻŽāϰāĻž āĻāχ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟāϟāĻžāϕ⧇ āĻāĻ•āϟāĻž āφāϞāĻžāĻĻāĻž āϏāĻžāĻ°ā§āĻ­āĻŋāϏ āĻŦāĻžāύāĻŋā§Ÿā§‡ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤ āϤāĻžāϰāĻĒāϰ āϝ⧇āĻ–āĻžāύ⧇ āϝ⧇āĻ–āĻžāύ⧇ āĻĻāϰāĻ•āĻžāϰ āĻ“āχ āϏāĻžāĻ°ā§āĻ­āĻŋāϏ āϟāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤

āφāϏāϞ āĻ•āĻĨāĻž āĻšāϞ, āϏāĻžāϧāĻžāϰāĻŖ āϭ⧁āϞāϗ⧁āϞ⧋ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇āĨ¤ āϝ⧇āĻŽāύāσ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āĻŽāĻ§ā§āϝ⧇ state āĻļā§‡ā§ŸāĻžāϰ āĻ•āϰāĻž, mutable āĻĄāĻžāϟāĻž āϟāĻžāχāĻĒ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž, āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āϗ⧁āϞ⧋āϕ⧇ āĻŽā§āϝāĻžāύ⧇āϜ āύāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻž āχāĻ¤ā§āϝāĻžāĻĻāĻŋāĨ¤ āϝāĻĻāĻŋ āϤ⧁āĻŽāĻŋ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āϗ⧁āϞ⧋āϕ⧇ āĻ āĻŋāĻ•āĻ āĻžāĻ• āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ āϤāĻžāĻšāϞ⧇ āϤ⧁āĻŽāĻŋ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻžāϰāĻĻ⧇āϰ āĻĨ⧇āϕ⧇ āĻļāĻžāĻ¨ā§āϤāĻŋāϤ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

// Global variable referenced by following function.
// If we had another function that used this name, now it'd be an array and it could break it.
let name = "Ryan McDermott";

function splitIntoFirstAndLastName() {
  name = name.split(" ");
}

splitIntoFirstAndLastName();

console.log(name); // ['Ryan', 'McDermott'];

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function splitIntoFirstAndLastName(name) {
  return name.split(" ");
}

const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name);

console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇ (āĻĒāĻžāĻ°ā§āϟ-2)

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ primitive āĻĄāĻžāϟāĻž pass-by-value āĻāĻŦāĻ‚ āĻāϰ⧇/āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ pass-by-reference āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻĢāĻžāĻ‚āĻļāύ⧇ āϝāĻžā§ŸāĨ¤ āĻāϰ⧇ āĻāĻŦāĻ‚ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āϝāĻĻāĻŋ āϤ⧋āĻŽāĻžāϰ āĻĢāĻžāĻ‚āĻļāύ āĻļāĻĒāĻŋāĻ‚ āĻ•āĻžāĻ°ā§āϟ āĻāϰ⧇āϤ⧇ āĻĄāĻžāϟāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āϤāĻŦ⧇ āĻ…āĻ¨ā§āϝ āϝāϤ āĻĢāĻžāĻ‚āĻļāύ cart āĻāϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϏāĻŦāĻžāϰ cart āĻāϰ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻšā§Ÿā§‡ āϝāĻžāĻŦ⧇āĨ¤ āĻāϟāĻž āĻšā§ŸāϤ āĻ­āĻžāϞ āĻŽāύ⧇ āĻšāĻšā§āϛ⧇, āĻāĻ•āϟāĻž āĻ–āĻžāϰāĻžāĻĒ āϕ⧇āϏ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāĻž āϝāĻžāĻ•,

āϧāϰ, āĻāĻ•āϜāύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āϤ⧋āĻŽāĻžāϰ āϏāĻžāχāĻŸā§‡āϰ "Purchase" āĻŦāĻžāϟāύ āĻ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϞ, āϝ⧇āϟāĻž āĻ•āĻŋāύāĻž "purchase" āĻŽā§‡āĻĨāĻĄ āϕ⧇ āĻ•āϞ āĻ•āϰ⧇ āĻāĻŦāĻ‚ cart āĻāϰ⧇ āϕ⧇ āύ⧇āϟāĻ“ā§ŸāĻžāĻ°ā§āĻ• āĻ•āϞ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻ āĻĒā§āϰ⧇āϰāĻŖ āĻ•āϰ⧇āĨ¤ āĻ–āĻžāϰāĻžāĻĒ āχāĻ¨ā§āϟāĻžāϰāύ⧇āϟ āĻ•āĻžāύ⧇āĻ•āĻļāύ āĻāϰ āĻ•āĻžāϰāϪ⧇, "purchase" āĻĢāĻžāĻ‚āĻļāύāϕ⧇ āĻŦāĻžāϰāĻŦāĻžāϰ āύ⧇āϟāĻ“ā§ŸāĻžāĻ°ā§āϕ⧇ āĻ•āϞ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻāĻ–āύ āϝāĻĻāĻŋ āĻĻ⧁āĻ°ā§āϘāϟāύāĻžāĻŦāĻļāϤ āϤ⧁āĻŽāĻŋ "Add to cart" āĻŦāĻžāϟāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ āϤāĻžāĻšāϞ⧇ āύāϤ⧁āύ āφāχāĻŸā§‡āĻŽ addItemToCart āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ cart āĻāϰ⧇āϤ⧇ āϝ⧋āĻ— āĻšā§Ÿā§‡ āϝāĻžāĻŦ⧇āĨ¤ āĻāĻŦāĻ‚ āύāϤ⧁āύ āφāχāĻŸā§‡āĻŽ āϏāĻš āϤ⧋āĻŽāĻžāϰ āϰāĻŋāĻ•ā§ā§Ÿā§‡āĻ¸ā§āϟ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻ āϚāϞ⧇ āϝāĻžāĻŦ⧇āĨ¤

āĻāϟāĻžāϰ āϖ⧁āĻŦ āĻ­āĻžāϞ⧋ āĻāĻ•āϟāĻž āϏāĻŽāĻžāϧāĻžāύ āĻšāϞ, addToItemCart āϏāĻŦ āϏāĻŽā§Ÿ cart āϕ⧇ āĻ•ā§āϞ⧋āύ āĻ•āϰ⧇ āύāϤ⧁āύ āĻāϰ⧇ āĻŦāĻžāύāĻžāĻŦ⧇, āϤāĻžāϰāĻĒāϰ āϏ⧇āχ āĻāϰ⧇āϤ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āύāϤ⧁āύ āĻāϰ⧇ āϟāĻž āϰāĻŋāϟāĻžāĻ°ā§āύ āĻ•āϰāĻŦ⧇āĨ¤ āĻāϤ⧇āĻ•āϰ⧇ āφāϏāϞ cart āĻāϰ⧇ āĻ…āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

āĻāχ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ ⧍ āϟāĻž āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāϛ⧇,

  1. āĻāĻŽāύ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝ⧇ āϤ⧋āĻŽāĻžāϰ āχāύāĻĒ⧁āϟ āĻ…āĻŦā§āĻœā§‡āĻ•ā§āϟāϟāĻžāχ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āĻĻāϰāĻ•āĻžāϰ, āĻ•ā§āϞ⧋āύ āĻ•āϰ⧇ āĻ•āĻžāϜ āĻšāĻšā§āϛ⧇āύāĻžāĨ¤ āϤāĻŦ⧇ āĻāϟāĻž āϖ⧁āĻŦāχ āĻ•āĻŽ āĻĻ⧇āĻ–āĻž āϝāĻžāĨ¤ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϜāĻŋāύāĻŋāĻļāχ āϏāĻžāχāĻĄ āχāĻĢ⧇āĻ•ā§āϟ āĻ›āĻžā§œāĻžāχ āϰāĻŋāĻĢā§āϝāĻžāĻ•ā§āϟāϰ āĻ•āϰāĻž āϝāĻžā§ŸāĨ¤
  2. āĻ…āύ⧇āĻ• āĻŦ⧜ āĻāĻ•āϟāĻž āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ•ā§āϞ⧋āύ āĻ•āϰāĻž āĻĒāĻžāĻ°ā§āĻĢāϰāĻŽā§‡āĻ¨ā§āϏ āĻāϰ āĻĒā§āϰ⧇āĻ•ā§āώāĻŋāϤ⧇ āϖ⧁āĻŦāχ āĻŦā§āϝ⧟āĻŦāĻšā§āϞāĨ¤ āϏ⧌āĻ­āĻžāĻ—ā§āϝāĻŦāĻļāϤ āĻŦāĻžāĻ¸ā§āϤāĻŦ⧇ āĻāĻŽāύ āύāĻž, āĻ•āĻžāϰāĻŖ āĻ•āĻŋāϛ⧁ āĻ…āϏāĻžāϧāĻžāϰāĻŖ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āφāϛ⧇ āϝāĻžāĻĻ⧇āϰ āĻ•āĻžāϰāϪ⧇ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ•ā§āϞ⧋āύāĻŋāĻ‚ āĻ…āύ⧇āĻ• āĻĻā§āϰ⧁āϤ āĻāĻŦāĻ‚ āĻ•āĻŽ āĻŽā§‡āĻŽāϰāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ•āϰāĻž āϝāĻžā§ŸāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const addItemToCart = (cart, item) => {
  cart.push({ item, date: Date.now() });
};

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const addItemToCart = (cart, item) => {
  return [...cart, { item, date: Date.now() }];
};

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ—ā§āϞ⧋āĻŦāĻžāϞ āĻĢāĻžāĻ‚āĻļāϞ⧇ āĻ•āĻŋāϛ⧁ āϞāĻŋāĻ–āĻŦ⧇ āύāĻž

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āĻ—ā§āϞ⧋āĻŦāĻžāϞ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ āĻ•āĻŋāϛ⧁ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϖ⧁āĻŦāχ āĻ–āĻžāϰāĻžāĻĒ āĻāĻ•āϟāĻŋ āĻ…āĻ­ā§āϝāĻžāϏāĨ¤ āĻ•āĻžāϰāĻŖ āĻ…āύ⧇āĻ• āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āĻ—ā§āϞ⧋āĻŦāĻžāϞ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĨ¤ āϤ⧋āĻŽāĻžāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻāϰ āĻ•āĻžāϰāϪ⧇ āϏ⧇āχāϏāĻŦ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āĻ•āĻžāĻœā§‡āϰ āĻŦā§āϝāϘāĻžāϤ āϘāϟāĻžāϰ āϏāĻŽā§āĻ­āĻžāĻŦāύāĻž āĻĨāĻžāϕ⧇āĨ¤ āĻāĻ•āϟāĻž āϏāĻŽā§āĻ­āĻžāĻŦāύāĻž āϧāϰāĻž āϝāĻžāĻ•, āĻ•āĻŋ āĻšāĻŦ⧇ āϝāĻĻāĻŋ āϤ⧁āĻŽāĻŋ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻāϰ⧇ āĻŽā§‡āĻĨāĻĄ āĻ "diff" āύāĻžāĻŽāĻ• āĻāĻ•āϟāĻŋ āĻŽā§‡āĻĨāĻĄ āϝ⧋āĻ— āĻ•āϰ, āϝ⧇āϟāĻž āĻ•āĻŋāύāĻž ⧍ āϟāĻž āĻāϰ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻĻ⧇āĻ–āĻžā§ŸāĨ¤ āĻāχ āĻŽā§‡āĻĨāĻĄāϟāĻž Array.prototype āĻ āϰāĻžāĻ–āϞ⧇, āĻ…āĻ¨ā§āϝ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āϝāĻĻāĻŋ āĻāĻ•āχ "diff" āύāĻžāĻŽāĻ• āĻŽā§‡āĻĨāĻĄ āĻĻāĻŋā§Ÿā§‡ āĻāĻ•āϟāĻž āĻāϰ⧇āϰ āĻĒā§āϰāĻĨāĻŽ āĻāĻŦāĻ‚ āĻļ⧇āώ āφāχāĻŸā§‡āĻŽ āĻāϰ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻĻ⧇āĻ–āĻžāϤ⧇ āϚāĻžā§Ÿ āϤāĻžāĻšāϞ⧇ āĻ•āĻŋ āĻšāĻŦ⧇? āĻāχ āϜāĻ¨ā§āϝ ES2015/ES6 āĻāϰ āĻ•ā§āϞāĻžāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ Array āĻ—ā§āϞ⧋āĻŦāĻžāϞ āϕ⧇ āĻāĻ•ā§āϏāĻŸā§‡āĻ¨ā§āĻĄ āĻ•āϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻŦ⧇āĻļāĻŋ āĻ­āĻžāϞ⧋āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

Array.prototype.diff = function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  return this.filter(elem => !hash.has(elem));
};

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class SuperArray extends Array {
  diff(comparisonArray) {
    const hash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āχāĻŽā§āĻĒ⧇āϰāĻžāϟāĻŋāĻ­ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻĨ⧇āϕ⧇ āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ āĻŦ⧇āĻļāĻŋ āϗ⧁āϰ⧁āĻ¤ā§āĻŦ āĻĻāĻžāĻ“

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻšāĻžāĻ¸ā§āϕ⧇āϞ āĻāϰ āĻŽāϤ āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ˛ā§āϝāĻžāĻ™ā§āĻ—ā§ā§Ÿā§‡āϜ āύāĻžāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāχāϟāĻžā§Ÿ āĻāĻ•āϧāϰāύ⧇āϰ āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻĢā§āϞ⧇āĻ­āĻžāϰ āφāϛ⧇āĨ¤ āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻ˛ā§āϝāĻžāĻ™ā§āĻ—ā§ā§Ÿā§‡āϜ āĻŸā§‡āĻ¸ā§āϟ āĻ•āϰāĻž āϤ⧁āϞāύāĻžāĻŽā§‚āϞāĻ•āĻ­āĻžāĻŦ⧇ āϏāĻšāϜāĨ¤ āϝāĻ–āύāχ āĻĒāĻžāϰāĻŦ⧇ āĻāχ āĻ¸ā§āϟāĻžāχāϞ⧇ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ•āϰāĻŦ⧇,

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const programmerOutput = [
  {
    name: "Uncle Bobby",
    linesOfCode: 500
  },
  {
    name: "Suzie Q",
    linesOfCode: 1500
  },
  {
    name: "Jimmy Gosling",
    linesOfCode: 150
  },
  {
    name: "Gracie Hopper",
    linesOfCode: 1000
  }
];

let totalOutput = 0;

for (let i = 0; i < programmerOutput.length; i++) {
  totalOutput += programmerOutput[i].linesOfCode;
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const programmerOutput = [
  {
    name: "Uncle Bobby",
    linesOfCode: 500
  },
  {
    name: "Suzie Q",
    linesOfCode: 1500
  },
  {
    name: "Jimmy Gosling",
    linesOfCode: 150
  },
  {
    name: "Gracie Hopper",
    linesOfCode: 1000
  }
];

const totalOutput = programmerOutput.reduce(
  (totalLines, output) => totalLines + output.linesOfCode,
  0
);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύāĻžāϞ āϕ⧇ āĻŦā§āϰāĻžāϕ⧇āϟ āĻĻāĻŋā§Ÿā§‡ āφāĻŦāĻĻā§āϧ āĻ•āϰ

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

if (fsm.state === "fetching" && isEmpty(listNode)) {
  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function shouldShowSpinner(fsm, listNode) {
  return fsm.state === "fetching" && isEmpty(listNode);
}

if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
  // ...
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āύ⧇āϗ⧇āϟāĻŋāĻ­ āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύāĻžāϞ āĻā§œāĻŋā§Ÿā§‡ āϚāϞ

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function isDOMNodeNotPresent(node) {
  // ...
}

if (!isDOMNodeNotPresent(node)) {
  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function isDOMNodePresent(node) {
  // ...
}

if (isDOMNodePresent(node)) {
  // ...
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύāĻžāϞ āĻā§œāĻŋā§Ÿā§‡ āϚāϞ

āĻļ⧁āϰ⧁āϤ⧇ āĻāϟāĻž āĻ…āϏāĻŽā§āĻ­āĻŦ āĻŽāύ⧇ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻŽāĻžāύ⧁āώ āĻāϟāĻž āĻļ⧁āύ⧇āχ āĻŦāϞāĻŦ⧇, "If āĻ¸ā§āĻŸā§‡āϟāĻŽā§‡āĻ¨ā§āϟ āĻ›āĻžā§œāĻž āφāĻŽāĻŋ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻ•āĻŋāϛ⧁ āĻ•āϰāĻŦā§‹?" āĻāϟāĻžāϰ āωāĻ¤ā§āϤāϰ āĻšāϞ, āφāĻŽāϰāĻž "Polymorphism" āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāϟāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤ āϤāĻ–āύ āϤāĻžāϰāĻž āϜāĻŋāĻœā§āĻžā§‡āϏ āĻ•āϰāĻŦ⧇, "āĻāϟāĻž āφāĻŽāĻŋ āϕ⧇āύ āĻ•āϰāĻŦ?" āĻāϟāĻžāϰ āωāĻ¤ā§āϤāϰ āĻšāϞ, āφāĻŽāϰāĻž āĻāϤāĻ•ā§āώāĻŖ āϝ⧇ āĻ•ā§āϞāĻŋāύ āϕ⧋āĻĄ āĻāϰ āύāĻŋ⧟āĻŽāύ⧀āϤāĻŋ āĻĒāϰ⧇ āφāϏāϞāĻžāĻŽ āϤāĻžāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻž, "āĻāĻ•āϟāĻž āĻĢāĻžāĻ‚āĻļāύ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻž āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇"āĨ¤ āϝāĻ–āύāχ āϤ⧋āĻŽāĻžāϰ āĻĢāĻžāĻ‚āĻļāύ⧇ if āĻĨāĻžāĻ•āĻŦ⧇ āϤāĻžāϰ āĻŽāĻžāύ⧇āχ āĻšāϞ āϤ⧋āĻŽāĻžāϰ āĻĢāĻžāĻ‚āĻļāύ āĻāĻ•āĻžāϧāĻŋāĻ• āĻ•āĻžāϜ āĻ•āϰāϛ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class Airplane {
  // ...
  getCruisingAltitude() {
    switch (this.type) {
      case "777":
        return this.getMaxAltitude() - this.getPassengerCount();
      case "Air Force One":
        return this.getMaxAltitude();
      case "Cessna":
        return this.getMaxAltitude() - this.getFuelExpenditure();
    }
  }
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class Airplane {
  // ...
}

class Boeing777 extends Airplane {
  // ...
  getCruisingAltitude() {
    return this.getMaxAltitude() - this.getPassengerCount();
  }
}

class AirForceOne extends Airplane {
  // ...
  getCruisingAltitude() {
    return this.getMaxAltitude();
  }
}

class Cessna extends Airplane {
  // ...
  getCruisingAltitude() {
    return this.getMaxAltitude() - this.getFuelExpenditure();
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϟāĻžāχāĻĒ āĻšā§‡āĻ•āĻŋāĻ‚ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇ (āĻĒāĻžāĻ°ā§āϟ-ā§§)

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āĻĢāĻžāĻ‚āĻļāύ āϝ⧇āϕ⧋āύ āϟāĻžāχāĻĒ⧇āϰ āĻĄāĻžāϟāĻž āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āĻšāĻŋāϏ⧇āĻŦ⧇ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻŽāĻžāĻā§‡ āĻŽāĻ§ā§āϝ⧇ āĻāχ āĻ¸ā§āĻŦāĻžāϧ⧀āύāϤāĻžāχ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϞ āĻšā§Ÿā§‡ āĻĻāĻžā§œāĻžā§ŸāĨ¤ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻ­āĻŋāϤāϰ⧇ āϟāĻžāχāĻĒ āĻšā§‡āĻ• āĻ•āϰāĻž āĻāĻ•āϟāĻž āϞ⧋āĻ­āĻ¨ā§€ā§Ÿ āĻ•āĻžāϜāĨ¤ āĻāϟāĻž āĻā§œāĻžāύāϰ āĻ…āύ⧇āĻ• āωāĻĒāĻžā§Ÿ āφāϛ⧇āĨ¤ āĻĒā§āϰāĻĨāĻŽ āĻ•āĻĨāĻž āĻšāϞ āĻāĻ•āϟāĻž āĻ¸ā§āĻĨāĻŋāϤāĻŋāĻļā§€āϞ API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function travelToTexas(vehicle) {
  if (vehicle instanceof Bicycle) {
    vehicle.pedal(this.currentLocation, new Location("texas"));
  } else if (vehicle instanceof Car) {
    vehicle.drive(this.currentLocation, new Location("texas"));
  }
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function travelToTexas(vehicle) {
  vehicle.move(this.currentLocation, new Location("texas"));
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϟāĻžāχāĻĒ āĻšā§‡āĻ•āĻŋāĻ‚ āĻā§œāĻŋā§Ÿā§‡ āϚāϞāϤ⧇ āĻšāĻŦ⧇ (āĻĒāĻžāĻ°ā§āϟ-2)

āϤ⧁āĻŽāĻŋ āĻŦ⧇āϏāĻŋāĻ• āĻĒā§āϰāĻŋāĻŽāĻŋāϟāĻŋāĻ­ āϝ⧇āĻŽāύ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚, āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ polymorphism āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āύāĻžāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āϤāĻŦ⧁āĻ“ āϤ⧋āĻŽāĻžāϰ āĻšā§ŸāϤ āϟāĻžāχāĻĒāĻšā§‡āĻ•āĻŋāĻ‚ āĻāϰ āĻĻāϰāĻ•āĻžāϰ āĻĒāϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āϤ⧁āĻŽāĻŋ Typescript āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāϰāĨ¤ āĻāϟāĻž āϏāĻžāϧāĻžāϰāĻŖ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āϖ⧁āĻŦ āĻ­āĻžāϞ⧋ āĻāĻ•āϟāĻž āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĨ¤ āĻāϟāĻž āĻ¸ā§āĻŸā§āϝāĻžāϟāĻŋāĻ• āϟāĻžāχāĻĒāĻŋāĻ‚ āϏāĻžāĻĒā§‹āĻ°ā§āϟ āĻ•āϰ⧇āĨ¤ āϏāĻžāϧāĻžāϰāĻŖ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āĻĒā§āϰāĻŦā§āϞ⧇āĻŽ āĻšāϞ āĻāϟāĻžā§Ÿ āϟāĻžāχāĻĒāĻšā§‡āĻ•āĻŋāĻ‚ āĻāϰ āϜāĻ¨ā§āϝ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁ āĻ•āϰāĻž āϞāĻžāϗ⧇ āϝ⧇āϟāĻž Typescript āĻ āϞāĻžāĻ—āĻŦ⧇ āύāĻžāĨ¤ āφāĻŦāĻžāϰāĻ“ āĻŦāϞāĻ›āĻŋ Typescript āϏāĻžāϧāĻžāϰāĻŖ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āϖ⧁āĻŦ āĻ­āĻžāϞ⧋ āĻāĻ•āϟāĻž āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function combine(val1, val2) {
  if (
    (typeof val1 === "number" && typeof val2 === "number") ||
    (typeof val1 === "string" && typeof val2 === "string")
  ) {
    return val1 + val2;
  }

  throw new Error("Must be of type String or Number");
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function combine(val1, val2) {
  return val1 + val2;
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāϜ āĻ•āϰāĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχ

āφāϧ⧁āύāĻŋāĻ• āĻŦā§āϰāĻžāωāϜāĻžāϰ āĻĒāĻ°ā§āĻĻāĻžāϰ āĻĒ⧇āĻ›āύ⧇ āĻ…āύ⧇āĻ• āϧāϰāϪ⧇āϰ āĻ…āĻĒāϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāύ āĻ•āϰ⧇āĨ¤ āĻ…āύ⧇āĻ• āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āχ āϤ⧋āĻŽāĻžāϰ āĻ…āĻĒāϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāύ āϏāĻŽā§Ÿā§‡āϰ āĻ…āĻĒāϚ⧟āĨ¤ āĻ•āĻžāϰāĻŖ āĻŦā§āϰāĻžāωāϜāĻžāϰ āĻāϟāĻž āύāĻŋāĻœā§‡āχ āφāĻŦāĻžāϰāĻ“ āĻ•āϰāĻŦ⧇āĨ¤ āϕ⧋āĻĨāĻžā§Ÿ āĻ…āĻĒāϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāύ āĻĻāϰāĻ•āĻžāϰ āϏ⧇āϟāĻž āĻšā§‡āĻ• āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϖ⧁āĻŦ āĻ­āĻžāϞ⧋ āϰāĻŋāϏ⧋āĻ°ā§āϏ āφāϛ⧇āĨ¤ āφāĻĒāĻžāϤāϤ āϏāϗ⧁āϞ⧋ āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāϜ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

// On old browsers, each iteration with uncached `list.length` would be costly
// because of `list.length` recomputation. In modern browsers, this is optimized.
for (let i = 0, len = list.length; i < len; i++) {
  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

for (let i = 0; i < list.length; i++) {
  // ...
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āĻŦā§āϝāĻŦāĻšā§ƒāϤ āϕ⧋āĻĄ āĻĢ⧇āϞ⧇ āĻĻāĻžāĻ“

āĻ…āĻŦā§āϝāĻŦāĻšā§ƒāϤ āϕ⧋āĻĄ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āϕ⧋āĻĄ āĻāϰ āĻŽāϤāχ āĻ–āĻžāϰāĻžāĻĒāĨ¤ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄāĻŦ⧇āĻœā§‡ āĻāϗ⧁āϞ⧋āϕ⧇ āϰāĻžāĻ–āĻžāϰ āϕ⧋āύ āĻ•āĻžāϰāĻŖ āύ⧇āχāĨ¤ āϤ⧁āĻŽāĻŋ āύāĻŋāĻļā§āϚāĻŋāĻ¨ā§āϤ⧇ āĻ…āĻŦā§āϝāĻŦāĻšā§ƒāϤ āϕ⧋āĻĄ āĻĢ⧇āϞ⧇ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧋āĨ¤ āĻ•āĻžāϰāĻŖ āĻāϗ⧁āϞ⧋ āĻ­āĻžāĻ°ā§āĻļāύ āĻšāĻŋāĻ¸ā§āϟāϰāĻŋ āϤ⧇ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function oldRequestModule(url) {
  // ...
}

function newRequestModule(url) {
  // ...
}

const req = newRequestModule;
inventoryTracker("apples", req, "www.inventory-awesome.io");

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function newRequestModule(url) {
  // ...
}

const req = newRequestModule;
inventoryTracker("apples", req, "www.inventory-awesome.io");

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ

āϗ⧇āϟāĻžāϰ āϏ⧇āϟāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ

āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĒā§āϰāĻĒāĻžāĻ°ā§āϟāĻŋ āĻ–ā§‹āϜāĻžāϰ āĻšā§‡ā§Ÿā§‡ āϗ⧇āϟāĻžāϰ āϏ⧇āϟāĻžāϰ āĻŽā§‡āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āĻĄāĻžāϟāĻž āĻāĻ•ā§āϏ⧇āϏ āĻ•āϰāĻž āĻ­āĻžāϞ⧋āĨ¤ āϤ⧁āĻŽāĻŋ āϜāĻŋāĻœā§āĻžā§‡āϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧋, āϕ⧇āύ? āύāĻŋāĻšā§‡ āĻāĻ•āϟāĻž āϞāĻŋāĻ¸ā§āϟ āĻĻāĻŋā§Ÿā§‡ āĻĻāĻŋāϞāĻžāĻŽ,

  • āϝāĻ–āύ āϤ⧁āĻŽāĻŋ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĒā§āϰāĻĒāĻžāĻ°ā§āϟāĻŋ āĻ–ā§‹āϜāĻžāϰ āĻšā§‡ā§Ÿā§‡ āφāϰāĻ“ āĻŦ⧇āĻļāĻŋ āĻ•āĻŋāϛ⧁ āĻ•āϰāϤ⧇ āϚāĻžāĻ“, āϤāĻ–āύ āϤ⧋āĻŽāĻžāϰ āϏāĻŦ āĻāĻ•ā§āϏ⧇āϏāϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āϞāĻžāĻ—āĻŦ⧇ āύāĻžāĨ¤
  • setter āĻŽā§‡āĻĨāĻĄ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϞ⧇ āĻ­ā§āϝāĻžāϞāĻŋāĻĄā§‡āĻļāύ āϏāĻšāϜ āĻšā§ŸāĨ¤
  • āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻšāĻŋāϤ āĻ…āĻĒā§āĻ°ā§Ÿā§‹āϜāĻ¨ā§€ā§Ÿ āĻĄāĻžāϟāĻž āφāĻŦāĻĻā§āϧ āĻĨāĻžāϕ⧇
  • getting āĻāĻŦāĻ‚ setting āĻāϰ āϏāĻŽā§Ÿ āϞāĻ— āĻ•āϰāĻž, āĻāϰāϰ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚ āĻ•āϰāĻž āϏāĻšāϜ āĻšā§ŸāĨ¤
  • āϤ⧁āĻŽāĻŋ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻĨ⧇āϕ⧇ āĻĄāĻžāϟāĻž āϞ⧋āĻĄ āĻ•āϰāĻžāϰ āϏāĻŽā§Ÿ 'lazy-load' āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function makeBankAccount() {
  // ...

  return {
    balance: 0
    // ...
  };
}

const account = makeBankAccount();
account.balance = 100;

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function makeBankAccount() {
  // this one is private
  let balance = 0;

  // a "getter", made public via the returned object below
  function getBalance() {
    return balance;
  }

  // a "setter", made public via the returned object below
  function setBalance(amount) {
    // ... validate before updating the balance
    balance = amount;
  }

  return {
    // ...
    getBalance,
    setBalance
  };
}

const account = makeBankAccount();
account.setBalance(100);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āĻ­āĻŋāϤāϰ⧇ āĻĒā§āϰāĻžāχāϭ⧇āϟ āĻŽā§‡āĻŽā§āĻŦāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ

āĻāϟāĻž āϤ⧁āĻŽāĻŋ 'closures' āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ(ES5 āĻāĻŦāĻ‚ āϤāĻžāϰ āύāĻŋāĻšā§‡)

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const Employee = function(name) {
  this.name = name;
};

Employee.prototype.getName = function getName() {
  return this.name;
};

const employee = new Employee("John Doe");
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function makeEmployee(name) {
  return {
    getName() {
      return name;
    }
  };
}

const employee = makeEmployee("John Doe");
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•ā§āϞāĻžāϏ

ES2015/ES6 āĻāϰ āĻ•ā§āϞāĻžāϏāϕ⧇ ES5 āĻāϰ āĻĢāĻžāĻ‚āĻļāύ āĻĨ⧇āϕ⧇ āĻŦ⧇āĻļāĻŋ āϗ⧁āϰ⧁āĻ¤ā§āĻŦ āĻĻāĻžāĻ“

ES5 āĻāϰ āĻ•ā§āϞāĻžāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϏ⧁āĻĒāĻžāĻ ā§āϝ āĻ•ā§āϞāĻžāϏ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ, āĻ•āĻ¨ā§āϏāĻŸā§āϰāĻžāĻ•āĻļāύ, āĻŽā§‡āĻĨāĻĄ āϞ⧇āĻ–āĻž āϖ⧁āĻŦāχ āĻ•āĻ āĻŋāύāĨ¤ āϤ⧋āĻŽāĻžāϰ āϝāĻĻāĻŋ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻĻāϰāĻ•āĻžāϰ āĻšā§Ÿ, āϏ⧇āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ ES2015/ES6 āĻ•ā§āϞāĻžāϏāϕ⧇ āĻĒā§āϰāĻžāϧāĻžāĻ¨ā§āϝ āĻĻāĻžāĻ“āĨ¤ āϤāĻŦ⧇ āϝāϤāĻ•ā§āώāĻŖ āύāĻž āϤ⧋āĻŽāĻžāϰ āĻŦ⧜ āĻāĻŦāĻ‚ āϜāϟāĻŋāϞ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āύāĻž āĻšāĻšā§āϛ⧇ āϤāϤāĻ•ā§āώāĻŖ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϛ⧋āϟ āĻĢāĻžāĻ‚āĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const Animal = function(age) {
  if (!(this instanceof Animal)) {
    throw new Error("Instantiate Animal with `new`");
  }

  this.age = age;
};

Animal.prototype.move = function move() {};

const Mammal = function(age, furColor) {
  if (!(this instanceof Mammal)) {
    throw new Error("Instantiate Mammal with `new`");
  }

  Animal.call(this, age);
  this.furColor = furColor;
};

Mammal.prototype = Object.create(Animal.prototype);
Mammal.prototype.constructor = Mammal;
Mammal.prototype.liveBirth = function liveBirth() {};

const Human = function(age, furColor, languageSpoken) {
  if (!(this instanceof Human)) {
    throw new Error("Instantiate Human with `new`");
  }

  Mammal.call(this, age, furColor);
  this.languageSpoken = languageSpoken;
};

Human.prototype = Object.create(Mammal.prototype);
Human.prototype.constructor = Human;
Human.prototype.speak = function speak() {};

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class Animal {
  constructor(age) {
    this.age = age;
  }

  move() {
    /* ... */
  }
}

class Mammal extends Animal {
  constructor(age, furColor) {
    super(age);
    this.furColor = furColor;
  }

  liveBirth() {
    /* ... */
  }
}

class Human extends Mammal {
  constructor(age, furColor, languageSpoken) {
    super(age, furColor);
    this.languageSpoken = languageSpoken;
  }

  speak() {
    /* ... */
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻŽā§‡āĻĨāĻĄ āĻšā§‡āχāύāĻŋāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āĻāχ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύāϟāĻŋ āϖ⧁āĻŦ āωāĻĒāĻ•āĻžāϰ⧀ āĻāĻŦāĻ‚ āϤ⧁āĻŽāĻŋ āĻ…āύ⧇āĻ• āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āϝ⧇āĻŽāύ jQuery, Lodash āĻ āĻāϰāĻ•āĻŽ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āĨ¤ āĻāϟāĻž āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āϕ⧇ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āϏāĻšāϜāĻŦā§‹āĻ§ā§āϝ āĻ•āϰ⧇ āϤ⧁āϞāĻŦ⧇āĨ¤ āĻāχ āϜāĻ¨ā§āϝ āĻŦāϞāĻŋ, āĻŽā§‡āĻĨāĻĄ āĻšā§‡āχāύāĻŋāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ āĻāĻŦāĻ‚ āĻĻ⧇āĻ– āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āφāϗ⧇āϰ āĻĨ⧇āϕ⧇ āĻ…āύ⧇āĻ• āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻšāĻŦ⧇āĨ¤ āϤ⧋āĻŽāĻžāϰ āĻ•ā§āϞāĻžāϏ āĻŽā§‡āĻĨāĻĄā§‡āϰ āĻļ⧇āώ⧇ this āϰāĻŋāϟāĻžāĻ°ā§āύ āĻ•āϰāϞ⧇āχ āĻšāĻŦ⧇āĨ¤ āϤāĻžāϰāĻĒāϰ āϤ⧁āĻŽāĻŋ āϏ⧇āχ āĻĢāĻžāĻ‚āĻļāύ⧇āĻ“ āĻŽā§‡āĻĨāĻĄ āĻšā§‡āχāύāĻŋāĻ‚ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }

  setMake(make) {
    this.make = make;
  }

  setModel(model) {
    this.model = model;
  }

  setColor(color) {
    this.color = color;
  }

  save() {
    console.log(this.make, this.model, this.color);
  }
}

const car = new Car("Ford", "F-150", "red");
car.setColor("pink");
car.save();

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }

  setMake(make) {
    this.make = make;
    // NOTE: Returning this for chaining
    return this;
  }

  setModel(model) {
    this.model = model;
    // NOTE: Returning this for chaining
    return this;
  }

  setColor(color) {
    this.color = color;
    // NOTE: Returning this for chaining
    return this;
  }

  save() {
    console.log(this.make, this.model, this.color);
    // NOTE: Returning this for chaining
    return this;
  }
}

const car = new Car("Ford", "F-150", "red").setColor("pink").save();

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻĨ⧇āϕ⧇ āĻ•āĻŽā§āĻĒā§‹āϜāĻŋāĻļāύ⧇ āϗ⧁āϰ⧁āĻ¤ā§āĻŦ āĻĻāĻžāĻ“

The gang of Four āĻāϰ āϞ⧇āĻ–āĻž āĻĄāĻŋāϜāĻžāχāύ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āĻ¨ā§āϏ āĻŦāĻ‡ā§Ÿā§‡ āϖ⧁āĻŦ āϜāύāĻĒā§āϰāĻŋ⧟ āĻāĻ•āϟāĻŋ āĻ•āĻĨāĻž āĻšāϞ, "āϝāĻ–āύāχ āĻĒāĻžāϰāĻŦ⧇ āϤāĻ–āύāχ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻĨ⧇āϕ⧇ āĻ•āĻŽā§āĻĒā§‹āϜāĻŋāĻļāύ āϕ⧇ āĻŦ⧇āĻļāĻŋ āϗ⧁āϰ⧁āĻ¤ā§āĻŦ āĻĻāĻŋāĻŦ⧇"āĨ¤ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āĻāĻŦāĻ‚ āĻ•āĻŽā§āĻĒā§‹āϜāĻŋāĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āĻ…āύ⧇āĻ• āĻ­āĻžāϞ⧋ āĻ•āĻžāϰāĻŖ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤ āĻŽā§‹āĻĻā§āĻĻāĻž āĻ•āĻĨāĻž āĻšāϞ, āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āĻ¸ā§āĻŦāϤāσāĻ¸ā§āĻĢā§‚āĻ°ā§āϤ āĻ­āĻžāĻŦ⧇āχ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰ āϝ⧇ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āϤ⧋āĻŽāĻžāϰ āϏāĻŽāĻ¸ā§āϝāĻžāϰ āϏāĻŽāĻžāϧāĻž āĻ•āϰāĻŦ⧇ āϤāĻŦ⧇ āφāϰ⧇āĻ•āĻŦāĻžāϰ āĻ­āĻžāĻŦ āϝ⧇ āĻ•āĻŽā§āĻĒā§‹āϜāĻŋāĻļāύ āĻĻāĻŋā§Ÿā§‡ āĻ•āĻžāϜ āϟāĻž āĻ•āϰāĻž āϝāĻžā§Ÿ āĻ•āĻŋāύāĻžāĨ¤ āĻ…āύ⧇āĻ• āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āχ āϤ⧁āĻŽāĻŋ āĻĒāĻžāϰāĻŦ⧇,

āϤ⧁āĻŽāĻŋ āĻšā§ŸāϤ āĻ­āĻžāĻŦāϤ⧇ āĻĒāĻžāϰ, "āϤāĻžāĻšāϞ⧇ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻ•āĻ–āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ"? āĻāϟāĻž āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āϤ⧋āĻŽāĻžāϰ āĻĒā§āϰāĻŦā§āϞ⧇āĻŽ āĻāϰ āωāĻĒāϰāĨ¤ āϝ⧇āϏāĻŦ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻ•āĻŽā§āĻĒāϜāĻŋāĻļāĻ¨ā§ āĻĨ⧇āϕ⧇ āĻ­āĻžāϞ⧋ āύāĻŋāĻšā§‡ āϤāĻžāϰ āĻāĻ•āϟāĻž āϞāĻŋāĻ¸ā§āϟ āĻĻāĻŋāϞāĻžāĻŽ,

  1. āϤ⧋āĻŽāĻžāϰ āχāύāĻšā§‡āϰāĻŋāĻŸā§‡āĻ¨ā§āϏ āĻ "has-a" āĻāϰ āĻŦāĻĻāϞ⧇ "is-a" āϏāĻŽā§āĻĒāĻ°ā§āĻ• āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύāĨ¤ (āĻŽāĻžāύ⧁āώ>āĻĒā§āϰāĻžāύāĻŋ vs. āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀>āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰāĻŋāϰ āϤāĻĨā§āϝ )
  2. āϤ⧁āĻŽāĻŋ āĻŦ⧇āϜ āĻ•ā§āϞāĻžāϏ āĻĨ⧇āϕ⧇ āϕ⧋āĻĄ āĻĒ⧁āύāϰāĻžā§Ÿ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāϞ⧇(human can move like all animals)āĨ¤
  3. āϤ⧁āĻŽāĻŋ āϚāĻžāχāĻ˛ā§āĻĄ āĻ•ā§āϞāĻžāϏ⧇ āĻ—ā§āϞ⧋āĻŦāĻžāϞ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āφāύāϤ⧇ āϚāĻžāĻ“ āĻŦ⧇āϜ āĻ•ā§āϞāĻžāϏ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡āĨ¤ (Change the caloric expenditure of all animals when they move).

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  // ...
}

// Bad because Employees "have" tax data. EmployeeTaxData is not a type of Employee
class EmployeeTaxData extends Employee {
  constructor(ssn, salary) {
    super();
    this.ssn = ssn;
    this.salary = salary;
  }

  // ...
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class EmployeeTaxData {
  constructor(ssn, salary) {
    this.ssn = ssn;
    this.salary = salary;
  }

  // ...
}

class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  setTaxData(ssn, salary) {
    this.taxData = new EmployeeTaxData(ssn, salary);
  }
  // ...
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

SOLID

Single Responsibility Principle (SRP)

āĻ•ā§āϞāĻŋāύ āϕ⧋āĻĄ āĻŦāĻ‡ā§Ÿā§‡ āϝ⧇āĻŽāύāϟāĻž āĻŦāϞāĻž āĻšā§Ÿā§‡āϛ⧇, "āĻāĻ•āϟāĻž āĻ•ā§āϞāĻžāϏ āĻ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻžāϰ āĻŦ⧇āĻļāĻŋ āĻ•āĻžāϰāύ āĻĨāĻžāĻ•āĻž āωāϚāĻŋāϤ āύāĻž"āĨ¤ āĻĢā§āϞāĻžāχāĻŸā§‡ āĻāĻ•āϟāĻž āĻŽāĻžāĻ¤ā§āϰ āϏ⧁āϟāϕ⧇āϏ āĻ¨ā§‡ā§ŸāĻžāϰ āĻŽāϤ, āĻāĻ•āϟāĻž āĻ•ā§āϞāĻžāϏ⧇ āĻ…āύ⧇āĻ• āĻĢāĻžāĻ‚āĻļāύ āĻĸ⧁āĻ•āĻŋā§Ÿā§‡ āĻĻā§‡ā§ŸāĻžāϟāĻž āϖ⧁āĻŦ āϞ⧋āĻ­āĻ¨ā§€ā§ŸāĨ¤ āĻāĻ•āϟāĻž āĻ•ā§āϞāĻžāϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āĻšāĻžāϰ āĻ•āĻŽāĻžāϤ⧇ āĻĒāĻžāϰāĻžāϟāĻž āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒ⧁āĻ°ā§āύ āĨ¤ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ āĻ•ā§āϞāĻžāϏ⧇ āĻ…āύ⧇āĻ• āĻĢāĻžāĻ‚āĻļāύ āϰāĻžāĻ–, āϤāĻŦ⧇ āĻāĻ•āϟāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āϕ⧋āĻĨāĻžā§Ÿ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻĒā§āϰāĻ­āĻžāĻŦ āĻĢ⧇āϞāϛ⧇ āĻŦ⧁āĻāϤ⧇ āĻĒāĻžāϰāĻž āĻ•āĻ āĻŋāύ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class UserSettings {
  constructor(user) {
    this.user = user;
  }

  changeSettings(settings) {
    if (this.verifyCredentials()) {
      // ...
    }
  }

  verifyCredentials() {
    // ...
  }
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class UserAuth {
  constructor(user) {
    this.user = user;
  }

  verifyCredentials() {
    // ...
  }
}

class UserSettings {
  constructor(user) {
    this.user = user;
    this.auth = new UserAuth(user);
  }

  changeSettings(settings) {
    if (this.auth.verifyCredentials()) {
      // ...
    }
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Open/Closed Principle (OCP)

āĻŦāĻžāϰāĻŸā§āϰāĻžāĻ¨ā§āĻĄ āĻŽā§‡ā§ŸāĻžāϰ āĻāϰ āĻŽāϤ⧇, "āϏāĻĢāϟāĻ“ā§ŸāĻžāϰ⧇āϰ āχāωāύāĻŋāϟ(āĻ•ā§āϞāĻžāϏ, āĻŽāĻĄāĻŋāωāϞāϏ, āĻĢāĻžāĻ‚āĻļāĻ¨ā§āϏ āχāĻ¤ā§āϝāĻžāĻĻāĻŋ) āϗ⧁āϞ⧋ āĻāĻ•ā§āϏāĻŸā§‡āĻ¨ā§āĻĄ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻ–ā§‹āϞāĻž āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇ , āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻŽāĻĄāĻŋāĻĢāĻŋāϕ⧇āĻļāύ⧇āϰ āϜāĻ¨ā§āϝ āĻŦāĻ¨ā§āϧ āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇" āĨ¤ āĻāϟāĻž āφāϏāϞ⧇ āĻ•āĻŋ āĻŦ⧁āĻāĻžā§Ÿ? āĻāϟāĻž āĻĻāĻŋā§Ÿā§‡ āφāϏāϞ⧇ āĻŦ⧁āĻāĻžā§Ÿ, āϤ⧋āĻŽāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϕ⧇ āύāϤ⧁āύ āĻĢāĻžāĻ‚āĻļāύ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĻāĻŋāϤ⧇ āĻšāĻŦ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϝ⧇ āĻĢāĻžāĻ‚āĻļāύ āφāϗ⧇ āĻĨ⧇āϕ⧇ āφāϛ⧇ āϏ⧇āϗ⧁āϞ⧋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āφāϟāĻ•āĻžāϤ⧇ āĻšāĻŦ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class AjaxAdapter extends Adapter {
  constructor() {
    super();
    this.name = "ajaxAdapter";
  }
}

class NodeAdapter extends Adapter {
  constructor() {
    super();
    this.name = "nodeAdapter";
  }
}

class HttpRequester {
  constructor(adapter) {
    this.adapter = adapter;
  }

  fetch(url) {
    if (this.adapter.name === "ajaxAdapter") {
      return makeAjaxCall(url).then(response => {
        // transform response and return
      });
    } else if (this.adapter.name === "nodeAdapter") {
      return makeHttpCall(url).then(response => {
        // transform response and return
      });
    }
  }
}

function makeAjaxCall(url) {
  // request and return promise
}

function makeHttpCall(url) {
  // request and return promise
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class AjaxAdapter extends Adapter {
  constructor() {
    super();
    this.name = "ajaxAdapter";
  }

  request(url) {
    // request and return promise
  }
}

class NodeAdapter extends Adapter {
  constructor() {
    super();
    this.name = "nodeAdapter";
  }

  request(url) {
    // request and return promise
  }
}

class HttpRequester {
  constructor(adapter) {
    this.adapter = adapter;
  }

  fetch(url) {
    return this.adapter.request(url).then(response => {
      // transform response and return
    });
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Liskov Substitution Principle (LSP)

This is a scary term for a very simple concept. It's formally defined as "If S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.)." That's an even scarier definition.

The best explanation for this is if you have a parent class and a child class, then the base class and child class can be used interchangeably without getting incorrect results. This might still be confusing, so let's take a look at the classic Square-Rectangle example. Mathematically, a square is a rectangle, but if you model it using the "is-a" relationship via inheritance, you quickly get into trouble.

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class Rectangle {
  constructor() {
    this.width = 0;
    this.height = 0;
  }

  setColor(color) {
    // ...
  }

  render(area) {
    // ...
  }

  setWidth(width) {
    this.width = width;
  }

  setHeight(height) {
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  setWidth(width) {
    this.width = width;
    this.height = width;
  }

  setHeight(height) {
    this.width = height;
    this.height = height;
  }
}

function renderLargeRectangles(rectangles) {
  rectangles.forEach(rectangle => {
    rectangle.setWidth(4);
    rectangle.setHeight(5);
    const area = rectangle.getArea(); // BAD: Returns 25 for Square. Should be 20.
    rectangle.render(area);
  });
}

const rectangles = [new Rectangle(), new Rectangle(), new Square()];
renderLargeRectangles(rectangles);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class Shape {
  setColor(color) {
    // ...
  }

  render(area) {
    // ...
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Square extends Shape {
  constructor(length) {
    super();
    this.length = length;
  }

  getArea() {
    return this.length * this.length;
  }
}

function renderLargeShapes(shapes) {
  shapes.forEach(shape => {
    const area = shape.getArea();
    shape.render(area);
  });
}

const shapes = [new Rectangle(4, 5), new Rectangle(4, 5), new Square(5)];
renderLargeShapes(shapes);

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Interface Segregation Principle (ISP)

āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āϝāĻĻāĻŋāĻ“ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āύāĻž āĻĨāĻžāĻ•āĻžāϰ āĻ•āĻžāϰāϪ⧇ āĻāχ āύ⧀āϤāĻŋ āĻ–āĻžāĻŸā§‡ āύāĻžāĨ¤ āϤāĻŦ⧇, āĻāϟāĻž āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒ⧁āĻ°ā§āύ āĻāĻŦāĻ‚ āφāύ⧁āϏāĻžāĻ‚āĻ—āĻŋāĻ•āĨ¤ ISP āĻ…āύ⧁āϝāĻžā§Ÿā§€, " āĻ•ā§āϞāĻžā§Ÿā§‡āĻ¨ā§āϟ āϝ⧇ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āύāĻž āϏ⧇āχ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āϚāĻžāĻĒāĻŋā§Ÿā§‡ āĻĻā§‡ā§ŸāĻž āϝāĻžāĻŦ⧇ āύāĻžāĨ¤ " āĻāχ āύ⧀āϤāĻŋāϟāĻŋ āĻŦ⧁āĻāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻž āĻ­āĻžāϞ⧋ āωāĻĻāĻžāĻšāϰāĻŖ āĻšāϞ, āĻ•ā§āϞāĻžāϏ⧇āϰ āϏ⧇āϟāĻŋāĻ‚ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āϕ⧇ āφāĻŦāĻļā§āϝāĻŋāĻ• āύāĻž āĻ•āϰāĻžāĨ¤ āĻāϤ⧇ āĻ•āϰ⧇ āϝ⧇ āϏāĻ•āϞ āĻ•ā§āϞāĻžāϏ⧇āϰ āϏ⧇āϟāĻŋāĻ‚ āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ…āύ⧇āĻ• āĻŦ⧜ āĻāĻŦāĻ‚ āĻ•ā§āϞāĻžā§Ÿā§‡āĻ¨ā§āĻŸā§‡āϰ āϏāĻŦ āϏ⧇āϟāĻŋāĻ‚ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āύ⧇āχ, āϏ⧇āϖ⧇āĻ¤ā§āϰ⧇ āφāĻŽāϰāĻž āĻāĻ•āϟāĻž āĻŦāĻŋāĻļāĻžāϞ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āĻŦāĻžāύāĻžāύ⧋ āĻĨ⧇āϕ⧇ āĻŦ⧇āĻšā§‡ āϝāĻžāχāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class DOMTraverser {
  constructor(settings) {
    this.settings = settings;
    this.setup();
  }

  setup() {
    this.rootNode = this.settings.rootNode;
    this.animationModule.setup();
  }

  traverse() {
    // ...
  }
}

const $ = new DOMTraverser({
  rootNode: document.getElementsByTagName("body"),
  animationModule() {} // Most of the time, we won't need to animate when traversing.
  // ...
});

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class DOMTraverser {
  constructor(settings) {
    this.settings = settings;
    this.options = settings.options;
    this.setup();
  }

  setup() {
    this.rootNode = this.settings.rootNode;
    this.setupOptions();
  }

  setupOptions() {
    if (this.options.animationModule) {
      // ...
    }
  }

  traverse() {
    // ...
  }
}

const $ = new DOMTraverser({
  rootNode: document.getElementsByTagName("body"),
  options: {
    animationModule() {}
  }
});

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Dependency Inversion Principle (DIP)

āĻāχ āĻŽā§‚āϞāύ⧀āϤāĻŋ ⧍āϟāĻž āϗ⧁āϰāĻ¤ā§āϤāĻĒ⧁āĻ°ā§āύ āϜāĻŋāύāĻŋāϏ āĻŦāϞ⧇ āĻĨāĻžāϕ⧇,

  1. āĻšāĻžāχ āϞ⧇āϭ⧇āϞ āĻŽāĻĄāĻŋāωāϞ āĻ•āĻ–āύ⧋āχ āϞ⧋ āϞ⧇āϭ⧇āϞ āĻŽāĻĄāĻŋāωāϞ āĻāϰ āωāĻĒāϰ⧇ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤
  2. āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āĻĄāĻŋāĻŸā§‡āχāϞ⧇āϰ āωāĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāĻŦ⧇āύ āύāĻžāĨ¤ āĻĄāĻŋāĻŸā§‡āχāϞ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ⧇āϰ āωāĻĒāϰ⧇ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāĻŦ⧇āĨ¤

āĻšā§ŸāϤ āϏāĻšāĻœā§‡ āĻŦ⧁āĻāĻŦ⧇ āύāĻž, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ AngularJS āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻĨāĻžāĻ•, āϤāĻžāĻšāϞ⧇ āĻāχ āĻŽā§‚āϞāύ⧀āϤāĻŋāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻĻ⧇āĻ–āĻžāϰ āĻ•āĻĨāĻžāĨ¤ AngularJS āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋ āχāύāĻœā§‡āĻ•āĻļāύ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻāχ āĻŽā§‚āϞāύ⧀āϤāĻŋāϰ āĻĒā§āĻ°ā§Ÿā§‹āĻ— āĻ•āϰ⧇āĨ¤ āϝāĻĻāĻŋāĻ“ ⧍ āϟāĻž āĻāĻ•āχ āϧāĻžāϰāĻŖāĻž āύāĻžāĨ¤ DIP āĻšāĻžāχ āϞ⧇āϭ⧇āϞ āĻŽāĻĄāĻŋāωāϞ āϕ⧇ āϞ⧋ āϞ⧇āϭ⧇āϞ āĻŽāĻĄāĻŋāωāϞ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϜāĻžāύāϤ⧇ āĻŦāĻžāϧāĻž āĻĻā§‡ā§ŸāĨ¤ āĻāϟāĻžāϰ āĻ…āύ⧇āĻ• āĻŦ⧜ āωāĻĒāĻ•āĻžāϰ āĻšāϞ, āĻāϟāĻž āĻŽāĻĄāĻŋāωāϞāϗ⧁āϞ⧋āϰ āĻŽāĻ§ā§āϝ⧇ āϕ⧋āύ āĻŦāĻ¨ā§āϧāύ āϰāĻžāϖ⧇āύāĻžāĨ¤ āĻ•āĻžāĻĒāϞāĻŋāĻ‚ āϕ⧋āĻĄ āϰ⧇āĻĢā§āϝāĻžāĻ•ā§āϟāϰ⧇āϰ āϜāĻ¨ā§āϝ āϖ⧁āĻŦ āĻ–āĻžāϰāĻžāĻĒ āĻāĻ•āϟāĻž āϜāĻŋāύāĻŋāϏāĨ¤

āφāϗ⧇āĻ“ āĻŦāϞāĻž āĻšā§Ÿā§‡āϛ⧇, āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āϕ⧋āύ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ āύāĻžāχ, āϏ⧁āϤāϰāĻžāĻ‚, āĻāĻ–āĻžāύ⧇ āĻ…ā§āϝāĻžāĻŦāĻ¸ā§āĻŸā§āϰāĻžāĻ•āĻļāύ āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻšāĻŋāϤ āĻ•āĻ¨ā§āĻŸā§āϰāĻžāĻ•ā§āϟ āĻāϰ āωāĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇āĨ¤ āĻŽāĻžāύ⧇ āĻāĻ•āϟāĻž āĻ•ā§āϞāĻžāϏ/āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻ…āĻ¨ā§āϝ āĻ•ā§āϞāĻžāϏ āĻŦāĻž āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻœā§‡āϰ āϝ⧇ āĻŽā§‡āĻĨāĻĄ āĻŦāĻž āĻŽā§‡āĻŽā§āĻŦāĻžāϰ āϗ⧁āϞ⧋ āωāĻ¨ā§āĻŽā§āĻ•ā§āϤ āĻ•āϰ⧇ āĻĻā§‡ā§Ÿ āϤāĻžāĻĻ⧇āϰāϕ⧇ āφāĻŽāϰāĻž āĻ•āĻ¨ā§āĻŸā§āϰāĻžāĻ•ā§āϟ āĻŦāϞāĻ›āĻŋāĨ¤ āύāĻŋāĻšā§‡āϰ āωāĻĻāĻžāĻšāϰāϪ⧇, inventoryTracker āĻāϰ āϝ⧇āϕ⧋āύ⧋ āĻŽāĻĄāĻŋāωāϞ āĻ requestitems āĻŽā§‡āĻĨāĻĄ āĻĨāĻžāĻ•āĻžāϟāĻžāχ implicit āĻ•āĻ¨ā§āĻŸā§āϰāĻžāĻ•ā§āϟ āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class InventoryRequester {
  constructor() {
    this.REQ_METHODS = ["HTTP"];
  }

  requestItem(item) {
    // ...
  }
}

class InventoryTracker {
  constructor(items) {
    this.items = items;

    // BAD: We have created a dependency on a specific request implementation.
    // We should just have requestItems depend on a request method: `request`
    this.requester = new InventoryRequester();
  }

  requestItems() {
    this.items.forEach(item => {
      this.requester.requestItem(item);
    });
  }
}

const inventoryTracker = new InventoryTracker(["apples", "bananas"]);
inventoryTracker.requestItems();

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class InventoryTracker {
  constructor(items, requester) {
    this.items = items;
    this.requester = requester;
  }

  requestItems() {
    this.items.forEach(item => {
      this.requester.requestItem(item);
    });
  }
}

class InventoryRequesterV1 {
  constructor() {
    this.REQ_METHODS = ["HTTP"];
  }

  requestItem(item) {
    // ...
  }
}

class InventoryRequesterV2 {
  constructor() {
    this.REQ_METHODS = ["WS"];
  }

  requestItem(item) {
    // ...
  }
}

// By constructing our dependencies externally and injecting them, we can easily
// substitute our request module for a fancy new one that uses WebSockets.
const inventoryTracker = new InventoryTracker(
  ["apples", "bananas"],
  new InventoryRequesterV2()
);
inventoryTracker.requestItems();

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚

āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻļāĻŋāĻĒāĻŋāĻ‚ āĻāϰ āĻĨ⧇āϕ⧇ āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒ⧁āĻ°ā§āύ āĨ¤ āϝāĻĻāĻŋ āϤ⧁āĻŽāĻŋ āĻ­āĻžāϞāĻ­āĻžāĻŦ⧇ āĻŸā§‡āĻ¸ā§āϟ āύāĻž āĻ•āϰ āĻŦāĻž āĻ•āĻŽ āĻŸā§‡āĻ¸ā§āϟ āĻ•āϰ, āϤāĻžāĻšāϞ⧇ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻļāĻŋāĻĒāĻŋāĻ‚ āĻāϰ āϏāĻŽā§Ÿ āϤ⧁āĻŽāĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āύāĻžāĨ¤ āĻĒāĻ°ā§āϝāĻžāĻĒā§āϤ āĻŸā§‡āĻ¸ā§āϟ āĻŦāϞāϤ⧇ āĻ•āĻŋ āĻŦ⧁āĻāĻžā§Ÿ āϏ⧇āϟāĻž āϤ⧋āĻŽāĻžāϰ āϟāĻŋāĻŽ āĻāϰ āωāĻĒāϰ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄ āĻ•āϰ⧇āĨ¤ āϤāĻŦ⧇ ā§§ā§Ļā§Ļ% āĻŸā§‡āĻ¸ā§āϟ āĻ•āĻ­āĻžāϰ⧇āϜ āĻĨāĻžāĻ•āϞ⧇ āϤ⧁āĻŽāĻŋ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āφāĻ¤ā§āĻŽāĻŦāĻŋāĻļā§āĻŦāĻžāϏ⧀ āĻāĻŦāĻ‚ āĻĄā§‡āϭ⧇āϞāĻĒ⧇āϰ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻļāĻžāĻ¨ā§āϤāĻŋ āϤ⧇ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰāĻŦ⧇āĨ¤ āϤāĻžāϰ āĻŽāĻžāύ⧇ āĻšāϞ āĻ­āĻžāϞ⧋ āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚ āĻĢā§āϰ⧇āĻŽāĻ“ā§ŸāĻžāĻ°ā§āĻ• āĻāϰ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻ­āĻžāϞ⧋ āĻ•āĻ­āĻžāϰ⧇āϜ āϟ⧁āϞ āĻ“ āĻĒā§āĻ°ā§Ÿā§‹āϜāύāĨ¤

āĻŸā§‡āĻ¸ā§āϟ āύāĻž āϞ⧇āĻ–āĻžāϰ āϕ⧋āύ āĻ…āϜ⧁āĻšāĻžāϤ āύ⧇āχāĨ¤ āĻ…āύ⧇āĻ• āĻ­āĻžāϞ⧋ āĻŸā§‡āĻ¸ā§āϟ āĻĢā§āϰ⧇āĻŽāĻ“ā§ŸāĻžāĻ°ā§āĻ• āφāϛ⧇āĨ¤ āϏ⧁āϤāϰāĻžāĻ‚, āϤ⧋āĻŽāĻžāϰ āϟāĻŋāĻŽ āϝ⧇āϟāĻž āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ⧇ āϏ⧇āϟāĻž āĻŦ⧇āϛ⧇ āύāĻžāĻ“āĨ¤ āϤāĻžāϰāĻĒāϰ āĻĒā§āϰāϤāĻŋāϟāĻž āύāϤ⧁āύ āĻĢāĻŋāϚāĻžāϰ, āĻŽāĻĄāĻŋāωāϞ āϞ⧇āĻ–āĻžāϰ āϏāĻŽā§Ÿ āĻŸā§‡āĻ¸ā§āϟ āϞ⧇āĻ–āĻž āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰāĨ¤ āϤ⧁āĻŽāĻŋ āϝāĻĻāĻŋ Test Driven Development āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ āϤāĻžāĻšāϞ⧇ āϖ⧁āĻŦ āĻ­āĻžāϞ⧋āĨ¤ āϤāĻŦ⧇ āφāϏāϞ āĻ•āĻĨāĻž āĻšāϞ, āĻĒā§āϰāϤāĻŋāϟāĻŋ āύāϤ⧁āύ āĻĢāĻŋāϚāĻžāϰ āĻļāĻŋāĻĒāĻŋāĻ‚ āĻāϰ āφāϗ⧇ āĻŸā§‡āĻ¸ā§āϟ āĻ•āĻ­āĻžāϰ⧇āϜ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰāĻžāĨ¤

āĻĒā§āϰāϤāĻŋ āĻŸā§‡āĻ¸ā§āϟ āĻ āĻāĻ•āϟāĻž āĻŽāĻžāĻ¤ā§āϰ āĻ•āύāϏ⧇āĻĒā§āϟ

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

import assert from "assert";

describe("MomentJS", () => {
  it("handles date boundaries", () => {
    let date;

    date = new MomentJS("1/1/2015");
    date.addDays(30);
    assert.equal("1/31/2015", date);

    date = new MomentJS("2/1/2016");
    date.addDays(28);
    assert.equal("02/29/2016", date);

    date = new MomentJS("2/1/2015");
    date.addDays(28);
    assert.equal("03/01/2015", date);
  });
});

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

import assert from "assert";

describe("MomentJS", () => {
  it("handles 30-day months", () => {
    const date = new MomentJS("1/1/2015");
    date.addDays(30);
    assert.equal("1/31/2015", date);
  });

  it("handles leap year", () => {
    const date = new MomentJS("2/1/2016");
    date.addDays(28);
    assert.equal("02/29/2016", date);
  });

  it("handles non-leap year", () => {
    const date = new MomentJS("2/1/2015");
    date.addDays(28);
    assert.equal("03/01/2015", date);
  });
});

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•āύāĻ•āĻžāϰ⧇āĻ¨ā§āϏāĻŋ

āĻ•āϞāĻŦā§āϝāĻžāĻ• āĻŦā§āϝāĻŦāĻšāĻžāϰ āύāĻž āĻ•āϰ⧇, āĻĒā§āϰāĻŽāĻŋāϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ

āĻ•āϞāĻŦā§āϝāĻžāĻ• āĻŽā§‡āĻĨāĻĄ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āύ⧇āĻ¸ā§āϟāĻŋāĻ‚ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤ ES2015/ES6 āĻāϰ āϏāĻžāĻĨ⧇ āĻĒā§āϰāĻŽāĻŋāϏ āĻ—ā§āϞ⧋āĻŦāĻžāϞ āϟāĻžāχāĻĒ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻĻā§‡ā§ŸāĻž āφāϛ⧇, āϏ⧇āϟāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

import { get } from "request";
import { writeFile } from "fs";

get(
  "https://en.wikipedia.org/wiki/Robert_Cecil_Martin",
  (requestErr, response, body) => {
    if (requestErr) {
      console.error(requestErr);
    } else {
      writeFile("article.html", body, writeErr => {
        if (writeErr) {
          console.error(writeErr);
        } else {
          console.log("File written");
        }
      });
    }
  }
);

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

import { get } from "request-promise";
import { writeFile } from "fs-extra";

get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin")
  .then(body => {
    return writeFile("article.html", body);
  })
  .then(() => {
    console.log("File written");
  })
  .catch(err => {
    console.error(err);
  });

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Async/Await āĻĒā§āϰāĻŽāĻŋāϏ āĻĨ⧇āϕ⧇āĻ“ āĻ­āĻžāϞ

āĻ•āϞāĻŦā§āϝāĻžāϕ⧇āϰ āϤ⧁āϞāύāĻžā§Ÿ āĻĒā§āϰāĻŽāĻŋāϏ āĻ…āύ⧇āĻ• āĻ­āĻžāϞāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ ES2017/ES8 āĻāϰ āϏāĻžāĻĨ⧇ asnyc āĻāĻŦāĻ‚ await āφāϛ⧇, āϝ⧇āϟāĻž āφāϰāĻ“ āĻ­āĻžāϞ⧋ āϏāĻŽāĻžāϧāĻžāύ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āϤ⧋āĻŽāĻžāϰ āĻļ⧁āϧ⧁ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āφāϗ⧇ async āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āϝāĻĻāĻŋ ES2017/ES8 āĻāϰ āϏ⧁āĻŦāĻŋāϧāĻž āύāĻŋāϤ⧇ āĻĒāĻžāϰ āϤāĻžāĻšāϞ⧇ āφāϜ āĻĨ⧇āϕ⧇āχ async āĻāĻŦāĻ‚ await āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

import { get } from "request-promise";
import { writeFile } from "fs-extra";

get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin")
  .then(body => {
    return writeFile("article.html", body);
  })
  .then(() => {
    console.log("File written");
  })
  .catch(err => {
    console.error(err);
  });

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

import { get } from "request-promise";
import { writeFile } from "fs-extra";

async function getCleanCodeArticle() {
  try {
    const body = await get(
      "https://en.wikipedia.org/wiki/Robert_Cecil_Martin"
    );
    await writeFile("article.html", body);
    console.log("File written");
  } catch (err) {
    console.error(err);
  }
}

getCleanCodeArticle()

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻāϰāϰ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚

āĻāϰāϰ āĻĨā§āϰ⧁ āĻ•āϰāĻž āĻāĻ•āϟāĻŋ āĻ­āĻžāϞ āϜāĻŋāύāĻŋāĻļāĨ¤ āϤāĻžāϰ āĻŽāĻžāύ⧇ āĻšāϞ āϤ⧋āĻŽāĻžāϰ āϰāĻžāύāϟāĻžāχāĻŽ āĻŦ⧁āĻāϤ⧇ āĻĒ⧇āϰ⧇āϛ⧇ āϝ⧇ āĻ•āĻŋāϛ⧁ āĻāĻ•āϟāĻž āϏāĻŽāĻ¸ā§āϝāĻž āφāϛ⧇āĨ¤

āĻāϰāϰ āϕ⧇ āĻ…āĻŦāĻœā§āĻžāĻž āĻ•āϰ āύāĻžāĨ¤

āĻāϰāϰ āĻĒ⧇āϞ⧇ āϏ⧇āϟāĻž āύāĻŋā§Ÿā§‡ āĻ•āĻŋāϛ⧁ āύāĻž āĻ•āϰāϞ⧇ āϤ⧁āĻŽāĻŋ āĻāϰāϰ āĻāϰ āĻ•āĻžāϰāĻŖ āĻŦ⧇āϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āύāĻž āĻāĻŦāĻ‚ āϤāĻžāϰ āϏāĻŽāĻžāϧāĻžāύ āĻ“ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āύāĻžāĨ¤ āĻ•āύāϏ⧋āϞ⧇ āĻāϰāϰ āϞāĻ— āĻ•āϰāĻž āϤ⧇āĻŽāύ āĻ­āĻžāϞ āϕ⧋āύ āϏāĻŽāĻžāϧāĻžāύ āύāĻžāĨ¤ āĻāϟāĻž āĻ•āύāϏ⧋āϞ⧇ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻšāĻ“ā§ŸāĻž āĻšāĻžāϜāĻžāϰāĻ“ āϜāĻŋāύāĻŋāϏ⧇āϰ āĻ­āĻŋā§œā§‡ āĻšāĻžāϰāĻŋā§Ÿā§‡ āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āϝāĻĻāĻŋ āϤ⧁āĻŽāĻŋ āϤ⧋āĻŽāĻžāϰ āϕ⧋āĻĄ āϕ⧇ try/catch āĻŦā§āϞāĻ• āĻ āφāĻŦāĻĻā§āϧ āĻ•āϰ āϤāĻžāϰ āĻŽāĻžāύ⧇ āĻšāϞ āϤ⧁āĻŽāĻŋ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻ› āĻāĻ–āĻžāύ⧇ āĻāĻ•āϟāĻž āĻāϰāϰ āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āϏ⧁āϤāϰāĻžāĻ‚ āϏ⧇āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āϤ⧋āĻŽāĻžāϰ āĻāĻ•āϟāĻž āĻĒāϰāĻŋāĻ•āĻ˛ā§āĻĒāύāĻž āĻĨāĻžāĻ•āĻž āωāϚāĻŋāϤāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

try {
  functionThatMightThrow();
} catch (error) {
  console.log(error);
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

try {
  functionThatMightThrow();
} catch (error) {
  // One option (more noisy than console.log):
  console.error(error);
  // Another option:
  notifyUserOfError(error);
  // Another option:
  reportErrorToService(error);
  // OR do all three!
}

āϰāĻŋāĻœā§‡āĻ•ā§āĻŸā§‡āĻĄ āĻĒā§āϰāĻŽāĻŋāϏ āϕ⧇ āĻ…āĻŦāĻœā§āĻžāĻž āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤

āϝ⧇āĻ•āĻžāϰāύ⧇ try/catch āĻ āϧāϰāĻž āĻāϰāϰ āϕ⧇ āĻ…āĻŦāĻœā§āĻžāĻž āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤ āĻāĻ•āχ āĻ•āĻžāϰāϪ⧇ āϰāĻŋāĻœā§‡āĻ•ā§āĻŸā§‡āĻĄ āĻĒā§āϰāĻŽāĻŋāϏāϕ⧇āĻ“ āĻ…āĻŦāĻœā§āĻžāĻž āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

getdata()
  .then(data => {
    functionThatMightThrow(data);
  })
  .catch(error => {
    console.log(error);
  });

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

getdata()
  .then(data => {
    functionThatMightThrow(data);
  })
  .catch(error => {
    // One option (more noisy than console.log):
    console.error(error);
    // Another option:
    notifyUserOfError(error);
    // Another option:
    reportErrorToService(error);
    // OR do all three!
  });

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚

āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚ āĻāĻ•āϟāĻž āϏāĻžāĻŦā§āĻœā§‡āϟāĻŋāĻ­ āĻŦā§āϝāĻĒāĻžāϰāĨ¤ āĻāĻ–āĻžāύ⧇ āĻ…āĻ¨ā§āϝ⧇ āϰ⧁āϞ⧇āϰ āĻŽāϤāχ āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚ āĻāϰ āĻ“ āϕ⧋āύ āϧāϰāĻžāĻŦāĻžāρāϧāĻž āύāĻŋ⧟āĻŽ āύ⧇āχāĨ¤ āφāϏāϞ āĻ•āĻĨāĻž āĻšāϞ, āĻ•āĻ–āύ⧋ āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚ āύāĻŋā§Ÿā§‡ āϤāĻ°ā§āĻ• āĻ•āϰāĻŦ⧇ āύāĻžāĨ¤ āĻ…āύ⧇āĻ• āϟ⧁āϞāϏāφāϛ⧇ āĻāχ āĻ•āĻžāϜ āϟāĻž āĻ…āĻŸā§‹āĻŽā§āϝāĻžāϟ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝāĨ¤ āϝ⧇āϕ⧋āύ⧋ āĻāĻ•āϟāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĨ¤ āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚ āύāĻŋā§Ÿā§‡ āϤāĻ°ā§āĻ• āĻ•āϰāĻž āϏāĻŽā§Ÿā§‡āϰ āĻ…āĻĒāϚ⧟ āĻ•āϰāĻž āĻ›āĻžā§œāĻž āφāϰ āĻ•āĻŋāϛ⧁ āύāĻžāĨ¤

āϝ⧇āϗ⧁āϞ⧋ āĻ…āĻŸā§‹ āĻĢāϰāĻŽā§āϝāĻžāϟāĻŋāĻ‚ āĻāϰ āφāĻ“āϤāĻžā§Ÿ āĻĒāϰ⧇ āύāĻž āϏ⧇āϗ⧁āϞ⧋āϰ āϜāĻ¨ā§āϝ āύāĻŋāĻšā§‡ āĻ•āĻŋāϛ⧁ āύāĻŋ⧟āĻŽ āĻĻā§‡ā§ŸāĻž āφāϛ⧇āĨ¤

āĻ¸ā§āĻĨāĻŋāϤāĻŋāĻļā§€āϞ āĻ•ā§āϝāĻžāĻĒāĻŋāϟāĻžāϞāĻžāχāϝ⧇āĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĨ¤

āϝ⧇āĻšā§‡āϤ⧁ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āφāĻ¨ā§āϟāĻžāχāĻĒāĻĄ āĻ˛ā§āϝāĻžāĻ™ā§āĻ—ā§ā§Ÿā§‡āϜ, āϤāĻžāχ āϝāĻĨāĻžāϝāĻĨ āĻ•ā§āϝāĻžāĻĒāĻŋāϟāĻžāϞāĻžāχāĻœā§‡āĻļāύ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϤāĻĨā§āϝ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻāχ āύāĻŋ⧟āĻŽāϗ⧁āϞ⧋āĻ“ āϏāĻžāĻŦā§āĻœā§‡āĻ•ā§āϟāĻŋāĻ­, āϤāĻžāχ āϤ⧋āĻŽāĻžāĻĻ⧇āϰ āϟāĻŋāĻŽ āĻāϰ āϏ⧁āĻŦāĻŋāϧāĻž āĻŽāϤ āĻāĻ•āϟāĻž āĻŦ⧇āϛ⧇ āύāĻŋāϞ⧇āχ āĻšāĻŦ⧇āĨ¤ āϤāĻŦ⧇ āϝ⧇āϟāĻžāχ āĻŦ⧇āϛ⧇ āύāĻžāĻ“ āύāĻž āϕ⧇āύ āϏ⧇āϟāĻžāϤ⧇āχ āĻ¸ā§āĻĨāĻŋāϰ āĻĨ⧇āϕ⧋āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

const DAYS_IN_WEEK = 7;
const daysInMonth = 30;

const songs = ["Back In Black", "Stairway to Heaven", "Hey Jude"];
const Artists = ["ACDC", "Led Zeppelin", "The Beatles"];

function eraseDatabase() {}
function restore_database() {}

class animal {}
class Alpaca {}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

const DAYS_IN_WEEK = 7;
const DAYS_IN_MONTH = 30;

const SONGS = ["Back In Black", "Stairway to Heaven", "Hey Jude"];
const ARTISTS = ["ACDC", "Led Zeppelin", "The Beatles"];

function eraseDatabase() {}
function restoreDatabase() {}

class Animal {}
class Alpaca {}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

Function callers and callees should be close

āϝāĻĻāĻŋ āĻāĻ•āϟāĻž āĻĢāĻžāĻ‚āĻļāύ āĻ…āĻ¨ā§āϝ āĻāĻ•āϟāĻžāϕ⧇ āĻ•āϞ āĻ•āϰ⧇, āϤāĻŦ⧇ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻŦ⧇ āĻāĻĻ⧇āϰāϕ⧇ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āϰāĻžāĻ–āϤ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }

  lookupPeers() {
    return db.lookup(this.employee, "peers");
  }

  lookupManager() {
    return db.lookup(this.employee, "manager");
  }

  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }

  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }

  getManagerReview() {
    const manager = this.lookupManager();
  }

  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

class PerformanceReview {
  constructor(employee) {
    this.employee = employee;
  }

  perfReview() {
    this.getPeerReviews();
    this.getManagerReview();
    this.getSelfReview();
  }

  getPeerReviews() {
    const peers = this.lookupPeers();
    // ...
  }

  lookupPeers() {
    return db.lookup(this.employee, "peers");
  }

  getManagerReview() {
    const manager = this.lookupManager();
  }

  lookupManager() {
    return db.lookup(this.employee, "manager");
  }

  getSelfReview() {
    // ...
  }
}

const review = new PerformanceReview(employee);
review.perfReview();

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•āĻŽā§‡āĻ¨ā§āϟāϏ

āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ•āĻŽāĻĒā§āϞ⧇āĻ•ā§āϏ āĻŦāĻŋāϜāύ⧇āϏ āϞāϜāĻŋāĻ• āϏāĻŽā§ƒāĻĻā§āϧ āϕ⧋āĻĄā§‡āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻ•āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰāĻŦ⧇āĨ¤

āĻ•āĻŽā§‡āĻ¨ā§āϟ āĻšāĻšā§āϛ⧇ āĻāĻ•āϧāϰāύ⧇āϰ āĻ•ā§āώāĻŽāĻž āĻĒā§āϰāĻžāĻ°ā§āĻĨāύāĻžāĨ¤ āĻ•āĻžāϰāĻŖ āĻ­āĻžāϞ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇āχ āύāĻŋāĻœā§‡āχ āύāĻŋāĻœā§‡āϰ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āϟ āĻšāĻŋāϏāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇, āĻ•āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰāĻžāϰ āĻĻāϰāĻ•āĻžāϰ āĻĒāϰ⧇ āύāĻžāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

function hashIt(data) {
  // The hash
  let hash = 0;

  // Length of string
  const length = data.length;

  // Loop through every character in data
  for (let i = 0; i < length; i++) {
    // Get character code.
    const char = data.charCodeAt(i);
    // Make the hash
    hash = (hash << 5) - hash + char;
    // Convert to 32-bit integer
    hash &= hash;
  }
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function hashIt(data) {
  let hash = 0;
  const length = data.length;

  for (let i = 0; i < length; i++) {
    const char = data.charCodeAt(i);
    hash = (hash << 5) - hash + char;

    // Convert to 32-bit integer
    hash &= hash;
  }
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ•āĻ–āύāχ āĻ•āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻĄ āϕ⧋āĻĄ āϰāĻžāĻ–āĻŦ⧇āύāĻž

āĻ­āĻžāĻ°ā§āĻļāύ āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞ āϤ⧈āϰāĻŋ āĻšāĻ“ā§ŸāĻžāϰ āĻāĻ•āϟāĻž āĻ•āĻžāϰāĻŖ āφāϛ⧇āĨ¤ āĻĒ⧁āϰāĻžāϤāύ āϕ⧋āĻĄ āϤ⧋āĻŽāĻžāϰ āĻšāĻŋāĻ¸ā§āĻŸā§‹āϰāĻŋāϤ⧇āχ āĻĨāĻžāĻ•āĻŦ⧇, āĻ•āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰ⧇ āϰāĻžāĻ–āĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχāĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

doStuff();
// doOtherStuff();
// doSomeMoreStuff();
// doSoMuchStuff();

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

doStuff();

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āϜāĻžāĻ°ā§āύāĻžāϞ āĻ•āĻŽā§‡āĻ¨ā§āϟ āϞāĻŋāĻ–āĻŦ⧇ āύāĻžāĨ¤

āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇, āĻ­āĻžāĻ°ā§āĻļāύ āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ git log āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ āĻšāĻŋāĻ¸ā§āĻŸā§‹āϰāĻŋ āĻĻ⧇āĻ–āϤ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

/**
 * 2016-12-20: Removed monads, didn't understand them (RM)
 * 2016-10-01: Improved using special monads (JP)
 * 2016-02-03: Removed type-checking (LI)
 * 2015-03-14: Added combine with type-checking (JR)
 */
function combine(a, b) {
  return a + b;
}

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

function combine(a, b) {
  return a + b;
}

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻĒāϜāĻŋāĻļāύāĻžāϞ āĻŽāĻžāĻ°ā§āĻ•āĻžāϰ āϰāĻžāĻ–āĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχāĨ¤

āĻāϗ⧁āϞ⧋ āφāϏāϞ⧇ āĻļ⧁āϧ⧁ āϏāĻŽāĻ¸ā§āϝāĻž āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤

āĻ–āĻžāϰāĻžāĻĒ āϕ⧋āĻĄ:

////////////////////////////////////////////////////////////////////////////////
// Scope Model Instantiation
////////////////////////////////////////////////////////////////////////////////
$scope.model = {
  menu: "foo",
  nav: "bar"
};

////////////////////////////////////////////////////////////////////////////////
// Action setup
////////////////////////////////////////////////////////////////////////////////
const actions = function() {
  // ...
};

āĻ­āĻžāϞ⧋ āϕ⧋āĻĄ:

$scope.model = {
  menu: "foo",
  nav: "bar"
};

const actions = function() {
  // ...
};

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

āĻ…āύ⧁āĻŦāĻžāĻĻ

This is also available in other languages:

âŦ† āωāĻĒāϰ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇

About

🛁 Clean Code concepts adapted for JavaScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%