<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何寫出干凈的 JavaScript 代碼

          共 16538字,需瀏覽 34分鐘

           ·

          2021-09-02 17:37

          一段干凈的代碼,你在閱讀、重用和重構(gòu)的時(shí)候都能非常輕松。編寫干凈的代碼非常重要,因?yàn)樵谖覀內(nèi)粘5墓ぷ髦校悴皇莾H僅是在為自己寫代碼。實(shí)際上,你還需要考慮一群需要理解、編輯和構(gòu)建你的代碼的同事。

          1. 變量

          使用有意義的名稱

          變量的名稱應(yīng)該是可描述,有意義的, JavaScript 變量都應(yīng)該采用駝峰式大小寫 ( camelCase) 命名。

          // Don't ?
          const foo = "[email protected]";
          const bar = "John";
          const age = 23;
          const qux = true;

          // Do ?
          const email = "[email protected]";
          const firstName = "John";
          const age = 23;
          const isActive = true

          布爾變量通常需要回答特定問(wèn)題,例如:

          isActive 
          didSubscribe 
          hasLinkedAccount

          避免添加不必要的上下文

          當(dāng)對(duì)象或類已經(jīng)包含了上下文的命名時(shí),不要再向變量名稱添加冗余的上下文。

          // Don't ?
          const user = {
            userId"296e2589-7b33-400a-b762-007b730c8e6d",
            userEmail"[email protected]",
            userFirstName"John",
            userLastName"Doe",
            userAge23,
          };

          user.userId;

          // Do ?
          const user = {
            id"296e2589-7b33-400a-b762-007b730c8e6d",
            email"[email protected]",
            firstName"John",
            lastName"Doe",
            age23,
          };

          user.id;

          避免硬編碼值

          確保聲明有意義且可搜索的常量,而不是直接插入一個(gè)常量值。全局常量可以采用 SCREAMING_SNAKE_CASE 風(fēng)格命名。

          // Don't ?
          setTimeout(clearSessionData, 900000);

          // Do ?
          const SESSION_DURATION_MS = 15 * 60 * 1000;

          setTimeout(clearSessionData, SESSION_DURATION_MS);

          2. 函數(shù)

          使用有意義的名稱

          函數(shù)名稱需要描述函數(shù)的實(shí)際作用,即使很長(zhǎng)也沒(méi)關(guān)系。函數(shù)名稱通常使用動(dòng)詞,但返回布爾值的函數(shù)可能是個(gè)例外 — 它可以采用 是或否 問(wèn)題的形式,函數(shù)名也應(yīng)該是駝峰式的。

          // Don't ?
          function toggle({
            // ...
          }

          function agreed(user{
            // ...
          }

          // Do ?
          function toggleThemeSwitcher({
            // ...
          }

          function didAgreeToAllTerms(user{
            // ...
          }

          使用默認(rèn)參數(shù)

          默認(rèn)參數(shù)比 && || 或在函數(shù)體內(nèi)使用額外的條件語(yǔ)句更干凈。

          // Don't ?
          function printAllFilesInDirectory(dir{
            const directory = dir || "./";
            //   ...
          }

          // Do ?
          function printAllFilesInDirectory(dir = "./"{
            // ...
          }

          限制參數(shù)的數(shù)量

          盡管這條規(guī)則可能有爭(zhēng)議,但函數(shù)最好是有3個(gè)以下參數(shù)。如果參數(shù)較多可能是以下兩種情況之一:

          • 該函數(shù)做的事情太多,應(yīng)該拆分。
          • 傳遞給函數(shù)的數(shù)據(jù)以某種方式相關(guān),可以作為專用數(shù)據(jù)結(jié)構(gòu)傳遞。
          // Don't ?
          function sendPushNotification(title, message, image, isSilent, delayMs{
            // ...
          }

          sendPushNotification("New Message""...""http://..."false1000);

          // Do ?
          function sendPushNotification({ title, message, image, isSilent, delayMs }{
            // ...
          }

          const notificationConfig = {
            title"New Message",
            message"...",
            image"http://...",
            isSilentfalse,
            delayMs1000,
          };

          sendPushNotification(notificationConfig);

          避免在一個(gè)函數(shù)中做太多事情

          一個(gè)函數(shù)應(yīng)該一次做一件事,這有助于減少函數(shù)的大小和復(fù)雜性,使測(cè)試、調(diào)試和重構(gòu)更容易。

          / Don't ?
          function pingUsers(users) {
            users.forEach((user) => {
              const userRecord = database.lookup(user);
              if (!userRecord.isActive()) {
                ping(user);
              }
            });
          }

          // Do ?
          function pingInactiveUsers(users) {
            users.filter(!isUserActive).forEach(ping);
          }

          function isUserActive(user) {
            const userRecord = database.lookup(user);
            return userRecord.isActive();
          }

          避免使用布爾標(biāo)志作為參數(shù)

          函數(shù)含有布爾標(biāo)志的參數(shù)意味這個(gè)函數(shù)是可以被簡(jiǎn)化的。

          // Don't ?
          function createFile(name, isPublic{
            if (isPublic) {
              fs.create(`./public/${name}`);
            } else {
              fs.create(name);
            }
          }

          // Do ?
          function createFile(name{
            fs.create(name);
          }

          function createPublicFile(name{
            createFile(`./public/${name}`);
          }

          避免寫重復(fù)的代碼

          如果你寫了重復(fù)的代碼,每次有邏輯改變,你都需要改動(dòng)多個(gè)位置。

          // Don't ?
          function renderCarsList(cars{
            cars.forEach((car) => {
              const price = car.getPrice();
              const make = car.getMake();
              const brand = car.getBrand();
              const nbOfDoors = car.getNbOfDoors();

              render({ price, make, brand, nbOfDoors });
            });
          }

          function renderMotorcyclesList(motorcycles{
            motorcycles.forEach((motorcycle) => {
              const price = motorcycle.getPrice();
              const make = motorcycle.getMake();
              const brand = motorcycle.getBrand();
              const seatHeight = motorcycle.getSeatHeight();

              render({ price, make, brand, nbOfDoors });
            });
          }

          // Do ?
          function renderVehiclesList(vehicles{
            vehicles.forEach((vehicle) => {
              const price = vehicle.getPrice();
              const make = vehicle.getMake();
              const brand = vehicle.getBrand();

              const data = { price, make, brand };

              switch (vehicle.type) {
                case "car":
                  data.nbOfDoors = vehicle.getNbOfDoors();
                  break;
                case "motorcycle":
                  data.seatHeight = vehicle.getSeatHeight();
                  break;
              }

              render(data);
            });
          }

          避免副作用

          在 JavaScript 中,你應(yīng)該更喜歡函數(shù)式模式而不是命令式模式。換句話說(shuō),大多數(shù)情況下我們都應(yīng)該保持函數(shù)純。副作用可能會(huì)修改共享狀態(tài)和資源,從而導(dǎo)致一些奇怪的問(wèn)題。所有的副作用都應(yīng)該集中管理,例如你需要更改全局變量或修改文件,可以專門寫一個(gè) util 來(lái)做這件事。

          // Don't ?
          let date = "21-8-2021";

          function splitIntoDayMonthYear({
            date = date.split("-");
          }

          splitIntoDayMonthYear();

          // Another function could be expecting date as a string
          console.log(date); // ['21', '8', '2021'];

          // Do ?
          function splitIntoDayMonthYear(date{
            return date.split("-");
          }

          const date = "21-8-2021";
          const newDate = splitIntoDayMonthYear(date);

          // Original vlaue is intact
          console.log(date); // '21-8-2021';
          console.log(newDate); // ['21', '8', '2021'];

          另外,如果你將一個(gè)可變值傳遞給函數(shù),你應(yīng)該直接克隆一個(gè)新值返回,而不是直接改變?cè)撍?/p>

          // Don't ?
          function enrollStudentInCourse(course, student{
            course.push({ student, enrollmentDateDate.now() });
          }

          // Do ?
          function enrollStudentInCourse(course, student{
            return [...course, { student, enrollmentDateDate.now() }];
          }

          3. 條件語(yǔ)句

          使用非負(fù)條件

          // Don't ?
          function isUserNotVerified(user{
            // ...
          }

          if (!isUserNotVerified(user)) {
            // ...
          }

          // Do ?
          function isUserVerified(user{
            // ...
          }

          if (isUserVerified(user)) {
            // ...
          }

          盡可能使用簡(jiǎn)寫

          // Don't ?
          if (isActive === true) {
            // ...
          }

          if (firstName !== "" && firstName !== null && firstName !== undefined) {
            // ...
          }

          const isUserEligible = user.isVerified() && user.didSubscribe() ? true : false;

          // Do ?
          if (isActive) {
            // ...
          }

          if (!!firstName) {
            // ...
          }

          const isUserEligible = user.isVerified() && user.didSubscribe();

          避免過(guò)多分支

          盡早 return 會(huì)使你的代碼線性化、更具可讀性且不那么復(fù)雜。

          // Don't ?
          function addUserService(db, user{
            if (!db) {
              if (!db.isConnected()) {
                if (!user) {
                  return db.insert("users", user);
                } else {
                  throw new Error("No user");
                }
              } else {
                throw new Error("No database connection");
              }
            } else {
              throw new Error("No database");
            }
          }

          // Do ?
          function addUserService(db, user{
            if (!db) throw new Error("No database");
            if (!db.isConnected()) throw new Error("No database connection");
            if (!user) throw new Error("No user");

            return db.insert("users", user);
          }

          優(yōu)先使用 map 而不是 switch 語(yǔ)句

          既能減少?gòu)?fù)雜度又能提升性能。

          // Don't ?
          const getColorByStatus = (status) => {
            switch (status) {
              case "success":
                return "green";
              case "failure":
                return "red";
              case "warning":
                return "yellow";
              case "loading":
              default:
                return "blue";
            }
          };

          // Do ?
          const statusColors = {
            success"green",
            failure"red",
            warning"yellow",
            loading"blue",
          };

          const getColorByStatus = (status) => statusColors[status] || "blue";

          使用可選鏈接

          const user = {
            email"[email protected]",
            billing: {
              iban"...",
              swift"...",
              address: {
                street"Some Street Name",
                state"CA",
              },
            },
          };

          // Don't ?
          const email = (user && user.email) || "N/A";
          const street =
            (user &&
              user.billing &&
              user.billing.address &&
              user.billing.address.street) ||
            "N/A";
          const state =
            (user &&
              user.billing &&
              user.billing.address &&
              user.billing.address.state) ||
            "N/A";

          // Do ?
          const email = user?.email ?? "N/A";
          const street = user?.billing?.address?.street ?? "N/A";
          const street = user?.billing?.address?.state ?? "N/A";

          4.并發(fā)

          避免回調(diào)

          回調(diào)很混亂,會(huì)導(dǎo)致代碼嵌套過(guò)深,使用 Promise 替代回調(diào)。

          // Don't ?
          getUser(function (err, user{
            getProfile(user, function (err, profile{
              getAccount(profile, function (err, account{
                getReports(account, function (err, reports{
                  sendStatistics(reports, function (err{
                    console.error(err);
                  });
                });
              });
            });
          });

          // Do ?
          getUser()
            .then(getProfile)
            .then(getAccount)
            .then(getReports)
            .then(sendStatistics)
            .catch((err) => console.error(err));

          // or using Async/Await ??

          async function sendUserStatistics({
            try {
              const user = await getUser();
              const profile = await getProfile(user);
              const account = await getAccount(profile);
              const reports = await getReports(account);
              return sendStatistics(reports);
            } catch (e) {
              console.error(err);
            }
          }

          5. 錯(cuò)誤處理

          處理拋出的錯(cuò)誤和 reject 的 promise

          / Don't ?
          try {
            // Possible erronous code
          } catch (e) {
            console.log(e);
          }

          // Do ?
          try {
            // Possible erronous code
          } catch (e) {
            // Follow the most applicable (or all):
            // 1- More suitable than console.log
            console.error(e);

            // 2- Notify user if applicable
            alertUserOfError(e);

            // 3- Report to server
            reportErrorToServer(e);

            // 4- Use a custom error handler
            throw new CustomError(e);
          }

          6.注釋

          只注釋業(yè)務(wù)邏輯

          可讀的代碼使你免于過(guò)度注釋,因此,你應(yīng)該只注釋復(fù)雜的邏輯。

          // Don't ?
          function generateHash(str{
            // Hash variable
            let hash = 0;

            // Get the length of the string
            let length = str.length;

            // If the string is empty return
            if (!length) {
              return hash;
            }

            // Loop through every character in the string
            for (let i = 0; i < length; i++) {
              // Get character code.
              const char = str.charCodeAt(i);

              // Make the hash
              hash = (hash << 5) - hash + char;

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

          // Do ?
          function generateHash(str{
            let hash = 0;
            let length = str.length;
            if (!length) {
              return hash;
            }

            for (let i = 0; i < length; i++) {
              const char = str.charCodeAt(i);
              hash = (hash << 5) - hash + char;
              hash = hash & hash; // Convert to 32bit integer
            }
            return hash;
          }

          使用版本控制

          在代碼里不需要保留歷史版本的注釋,想查的話你直接用 git log 就可以搜到。。

          // Don't ?
          /**
           * 2021-7-21: Fixed corner case
           * 2021-7-15: Improved performance
           * 2021-7-10: Handled mutliple user types
           */

          function generateCanonicalLink(user{
            // const session = getUserSession(user)
            const session = user.getSession();
            // ...
          }

          // Do ?
          function generateCanonicalLink(user{
            const session = user.getSession();
            // ...
          }

          好了,去寫出你漂亮的代碼吧!??

          螞蟻前端正急缺人才,如果你想加入我們,歡迎加我微信和我聯(lián)系。另外如果你想加入前端、面試、理財(cái)?shù)冉涣魅?,或者你有任何其他事情想和我交流也可以添加我的個(gè)人微信 1076629390 。

          文中如有錯(cuò)誤,歡迎在后臺(tái)和我留言,如果這篇文章幫助到了你,歡迎點(diǎn)贊、在看和關(guān)注。你的點(diǎn)贊、在看和關(guān)注是對(duì)我最大的支持!

          點(diǎn)贊、在看支持作者??

          瀏覽 35
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费看黄 片,在线观看 | 男女乱伦视频 | AV青青草 | 中国美女毛片 | 久久久久9999 |