前端都在聊什麼 - 第 3 期

jsliang發表於2023-02-25

Hello 小夥伴們早上、中午、下午、晚上、深夜好,我是愛折騰的 jsliang~

前端都在聊什麼」是 jsliang 日常寫文章/做影片/玩直播過程中,小夥伴們的提問以及我的解疑整理。

本文章影片同步:https://www.bilibili.com/vide...

本期對應 2023 年的 01.24 當天直播間的粉絲互動。

主要講 jsliang 這個 React 菜雞,幫忙分析 Vue 多層巢狀時介面不渲染問題,以及對程式碼風格的一些見解。

你的 關注點贊 是我持續更新的動力?,謝謝大家~

003-01.png

一 嗨!介面咋不出來

首先,那天小夥伴求助過來,我是很懵的。

因為我這 React 小菜雞,沒法確認是否能幫忙解決到問題。

如果最後沒幫忙解決掉問題,想必會被打得很慘吧~

003-02.png

然後,想著大過年的,小夥伴還在惦記這個問題,能幫一個是一個吧~

那就問清楚問題,幫忙分析分析!

小夥伴描述說:

用 Vue 耍級聯操作元件
一開始一級聯動沒問題,能獲取到資料並渲染
但是多級巢狀出問題了,資料獲取到了,但是渲染失敗
嘗試過用 `setTimeout`,效果不好

於是,聽完描述後,我開始反覆看 ta 程式碼,並開始 Google 之旅。

003-03.png

大概花了 40 分鐘後,嘗試用自己知識但發現沒鳥用後,終於找到一個貌似可行的解釋:

003-04.png

最終透過 vm.$forceUpdate() 解決了這次「臉面」危機~

同樣碰到資料渲染問題的小夥伴,可以看看這篇文章 Vue 資料更新了但頁面沒有更新的 7 種情況彙總及延伸總結

二 嘮嗑!程式碼風格爭議

解決完小夥伴問題後,俺也是理直氣壯了一回,於是跟小夥伴討論下他們程式碼風格問題。

當然,小夥伴也說明了,他們的程式碼由多個成員參與,沒有統一的 Lint,所以才會出現這個問題。

所以全程溝通氛圍 “非常友好”,切勿瞎想妄議~

2.1 層級縮排 - 2 空格 4 空格之爭

003-05.png

像上面程式碼貼圖,一會 2 空格,一會 4 空格的,團隊規範很是問題。

JavaScript 有個很奇怪的爭論:用 2 空格還是 4 空格比較合適

第一次瞭解到這個區分的,還是因為工作中寫 2 空格被大佬吐槽。

後面跟大佬混熟後,我搞懂了:

  • 螢幕比較「大」的,都喜歡 4 空格
  • 螢幕比較「小」的,都喜歡 2 空格

003-06.png

震驚我一整年!!

這讓我這個用膝上型電腦,然後外接顯示器的情何以堪~

變身,直接成為中間黨!你強任你強,能跑就成王。

2.2 註釋位置 - 前置還是後置

003-07.png

關於註釋位置放到行尾還是上方,其實是較有爭議的:

  • 行尾
const name = 'jsliang'; // 這是我的網名
  • 上方
// 這是我的網名
const name = 'jsliang';

在公司團隊合作的時候,也會碰到這種衝突。

因為專案構建問題,註釋可能會被單獨一行,所以會導致出現下面的情況:

const name = 'jsliang';
// 這是我的網名

所以在工作中養成了習慣,程式碼註釋在上方單獨一行。

不過感覺如果是一些比較簡短的註釋,放在行尾也是 OK 的,例如:

const name = 'jsliang'; // 網名
const age  = 28;
const like = 'play'; // 愛好

// ?這個常量做什麼的,如果沒有註釋怎麼理解
const TODO = [];
糟糕!現在看行尾註釋有點不習慣了~

個人覺得主要還是變數名問題。

因為有些變數名,英文翻譯出來有多個意思,所以才需要我們透過註釋來加強解釋。

所以工作中,不太容易理解的變數名和方法函式,最好加上註釋。

感興趣的小夥伴可以關注下 JSDoc:https://www.jsdoc.com.cn/

2.3 _this = this? 令人抓狂

下面是 Vue 中,一個我現在也沒想明白的操作:

003-08.png

jsliang 查了下,Vue 上這麼寫是因為有 this 指向問題,所以才需要:

const _this = this;

可參考:Vue 中 的 var that=this 語句是什麼意思?

雖然上面帖子討論可以使用箭頭函式,但是我還是順帶查詢了下 Vue 官網。

裡面也說明清楚,宣告方法時應當避免使用箭頭函式:

003-09.png

仁者見仁,如果有 Vue 比較熟練的小夥伴,可以評論區下留言關於自己對這塊的見解~

2.4 var/let 和 const

003-10.png

在文章 document-library/系列-面試資料/JavaScript/變數 中,我們探討過。

對於 var,因為存在不可控因素:

  • var 宣告的變數會預解析,提升到全域性變數上,影響整個 JS 指令碼

舉個例子:

var temp = new Date();

function f(){
  console.log(temp);
  if(false){
    var temp = "hello";
  }
}

f(); // undefined

在這個程式碼塊執行的時候,temp 被預解析了,提升上去了,於是成為:

var temp = new Date();

function f(){
+  var temp;
  console.log(temp);
  if(false){
-    var temp = "hello";
+    temp = "hello";
  }
}

f(); // undefined

所以 ES6 出來了 letconst

在變數型別和值不確認的情況,使用 let,在操作常量以及固定型別的時候,使用 const

let age = 28;
const name = 'jsliang';

const info = {
  name,
  age,
};
// name: 'jsliang', age: 28
console.log(info);

// 一年後
const after1Year = () => {
  age++;
};
after1Year();

const newInfo = {
  name,
  age,
};
// name: 'jsliang', age: 29
console.log(newInfo);

更多可以前往 document-library/系列-面試資料/JavaScript/變數 瞭解。

003-11.png

2.5 資料解構 - a.b.c.d

這個問題在工作中非常常見:

003-12.png

在反覆呼叫的時候,尤其是 window.xxx 形式比較多,需要查詢裡面屬性的時候。

這樣子寫程式碼比較難閱讀。

可以嘗試這麼最佳化:

// 1. 就是獲取,並且相容
const dataset = e.currentTarget.dataset || {};
// 2. 解構獲取
const { id, name, pid, pindex } = dataset;
// 3. 做其他操作
// 注意確保是否需判斷 id/name 的相容性
// 如果可能為 undefined,那應該 if (id) {}

2.6 物件中 key 和 value 命名相同

下面有 2 個可以嘗試提升閱讀體驗的操作。

003-13.png

嘗試最佳化:

queryfntQueryVillage({
  // param: param
  param
}).then((res) => {
  // ...todo
});

003-14.png

嘗試最佳化:

// _this.result[_this.navCurrentIndex] = { id: id, name: name, pid: pid };
_this.result[xxx] = { id, name, pid };

這 2 個操作,可以讓程式碼看起來更精簡。

2.7 forEach 和 for 的使用

003-15.png

時至今日,看到上面程式碼,隱隱約約還是會有點頭皮發麻的感覺。

我們應該理解,forEach 並不會中止後續的迴圈。

所以當資料過多的時候,對效能來說是個高挑戰。

當你有 1w 條資料,雖然我第 1 條就找到了,但是它仍然會遍歷 1w 遍。

所以這種情況下,使用 for 可以及時止損。

const data = _this.data;
for (let i = 0; i < data.length; i++) {
  const item = data[i];
  if (item.id === pid) {
    // ...
    // 中止後續迴圈,因為我已經找到了
    break;
  }
}

雖然 ES6 新增了 forEachmap 等實用函式,但是編寫程式碼的時候,可以稍微注意下效能問題。

2.8 冗餘程式碼問題

下面我們看一份程式碼:

003-16.png

很明顯,我們透過 VS Code 區選程式碼的時候,直接在同一排發現有多個重複呼叫程式碼。

const children = _this._deepQuery(_this.data, id).children;
const isDefineChildren = _this.isDefine(children);
if (
  (!_this.isDefine(_this.layer) && isDefineChildren)
  || (_this.navCurrentIndex < (Number(_this.layer) - 1) && isDefineChildren)
) {
  children.forEach((item, index) => {
    const { id, name } = item;
    _arr.push({ id, name, pid: id});
  });
}

這樣,我們就讓程式碼看起來更容易理解了。

2.9 \`\` 和 '' 以及 "" 的使用

很多時候,我們會糾結這 3 種符號的使用,例如:

003-17.png

jsliang 為了讓自己工作不再糾結,給自己定了小規範:

  1. 在 HTML 上,統一使用雙引號,例如 class="",又或者 data-value=""
  2. 在 JavaScript 上,定義變數等一律使用 '',例如 const name = 'jsliang'
  3. 在拼接字元上,統一使用 \`\`,例如:
const name = 'jsliang';
const info = `你好 ${name}
歡迎來到 2077 地球~
`;
const render = () => {
  return (
    <div className="react-class"></div>
  );
};

2.10 =====

這一點想必很多小夥伴也瞭解:

003-18.png

像上面這種判斷的時候,很容易出簍子。

舉個例子:

const d = 1;
const e = '1';
console.log(d == e);
console.log(d === e);

像這裡,1 等於 '1' 嗎?

如果你是使用 ==,那麼它只會判斷值是否相等,才不管你型別長啥樣。

而使用 ===,它還會判斷型別是否一樣。

三 參考文獻


不折騰的前端,和鹹魚有什麼區別!

覺得文章不錯的小夥伴歡迎點贊/點 Star。

如果小夥伴需要聯絡 jsliang

個人聯絡方式存放在 Github 首頁,歡迎一起折騰~

爭取打造自己成為一個充滿探索欲,喜歡折騰,樂於擴充套件自己知識面的終身學習斜槓程式設計師。

jsliang 的文件庫由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的作品創作。<br/>本許可協議授權之外的使用許可權可以從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處獲得。

相關文章