摘要:例外回調(diào)函數(shù)生命周期函數(shù)框架級(jí)別函數(shù)說(shuō)明函數(shù)的命名需要體現(xiàn)內(nèi)部工作值變量以動(dòng)詞命名容易讓人誤解為是一個(gè)匿名函數(shù)以名詞開(kāi)頭,看不明白什么有什么功能時(shí)態(tài)不對(duì)規(guī)則避免使用拼音或者縮寫(xiě)命名。前端代碼處理錯(cuò)誤的方式一般為提示用戶有異常發(fā)生。
命名 規(guī)則:除非在小于 5 行的函數(shù)里,否則不要使用單字命名變量
說(shuō)明:含義不清晰,不能做到「望文生義」
BadCode
var l = data.length;
GoodCode
// 閉包只有一行代碼,可以使用單字變量 data.map(d => d.length)規(guī)則:不要使用名詞加數(shù)字的命名方法
說(shuō)明:含義不清晰,不能做到「望文生義」
BadCode
var obj = {}; var obj2 = {...obj, key: 1};
GoodCode
var obj = {}; var objWithKey = {...obj, key: 1};規(guī)則:應(yīng)該且只有方法和函數(shù)以動(dòng)詞開(kāi)頭
此處動(dòng)詞沒(méi)有包含時(shí)態(tài)
變量名應(yīng)該是名詞或者名詞短語(yǔ)。
例外:
回調(diào)函數(shù)
生命周期函數(shù)
框架級(jí)別函數(shù)
getter/setter
說(shuō)明:
函數(shù)的命名需要體現(xiàn)內(nèi)部工作
值變量以動(dòng)詞命名容易讓人誤解為是一個(gè)匿名函數(shù)
BadCode
// 以名詞開(kāi)頭,看不明白什么有什么功能 function option() {} // 時(shí)態(tài)不對(duì) function updatedTime() {}
GoodCode
function selectOption() {} function updateTime() {}規(guī)則:避免使用拼音或者縮寫(xiě)命名。
例外:
專(zhuān)有名詞:weixin/POI
傳統(tǒng)約定:i/j/k 表示循環(huán)索引
說(shuō)明:含義不清晰,不能做到「望文生義」
BadCode
var uo = function updateOrder(){} var as = [].slice; var ex = Object.extends; var nu = number
GoodCode
// weixin/wx 是專(zhuān)有名詞 var weixinUser = {}; var wx = weixin; // POI 是專(zhuān)有名詞 var poi = {};規(guī)則:名稱(chēng)長(zhǎng)短應(yīng)與其作用域大小相對(duì)應(yīng)。
例外:專(zhuān)有 API,如 alert
說(shuō)明:在上層作用域下的代碼,會(huì)被更多函數(shù)使用到。其名稱(chēng)應(yīng)該盡量長(zhǎng)或者通用,以保證能夠搜索到。
BadCode
// 在全局變量上定義了一個(gè) item 變量,但是很難從命名上理解其作用是什么。 window.item = {}
GoodCode
window.primaryProductItem = {};不要在變量/函數(shù)尾部加符號(hào)、數(shù)字
說(shuō)明:變量中加符號(hào),往往是為了約定其優(yōu)先級(jí)或者作用域。符號(hào)應(yīng)該在變量名前面。
BadCode
function getDot_(){} function privateFn$$ (){}
GoodCode
function _getDot() {} function $$privateFn() {}規(guī)則:實(shí)例名稱(chēng)要和類(lèi)名相關(guān)
說(shuō)明:類(lèi)作為實(shí)例的所屬,其名稱(chēng)表達(dá)的含義要一脈相承
BadCode
class Person() {} var dog = new Person(); // dog is a Person ?
GoodCode
class Person() {} var jack = new Person();規(guī)則:避免直白的中英文翻譯
說(shuō)明:粗暴的翻譯,更容易造成誤解,還不如寫(xiě)拼音
BadCode
// 渲染「頁(yè)面頂部的執(zhí)行人」 // 還是渲染「執(zhí)行砍頭的人」? function renderHeadExecutantPeople(){}
GoodCode
function renderHeader() {}規(guī)則:概念的命名要一以貫之
說(shuō)明:避免通一個(gè)概念在不同的代碼用多種不同的單詞描述。
BadCode
// 遠(yuǎn)程請(qǐng)求這個(gè)概念,先后用了 get/fetch/query // 三個(gè)名詞去描述 function getUserInfo() {} function fetchProductInfo() {} function queryPayment() {}
GoodCode
// 統(tǒng)一用 get 描述 // 閱讀代碼的人能體會(huì)到其中的共性 function getUserInfo() {} function getProductInfo() {} function getPayment() {}規(guī)則:別用雙關(guān)語(yǔ)
例外:專(zhuān)有詞
說(shuō)明:雙關(guān)語(yǔ)容易引起歧義
BadCode
// 訂單類(lèi)型,還是排序類(lèi)型? var orderType
GoodCode
var sortType規(guī)則:命名需要和實(shí)現(xiàn)一致
說(shuō)明:命名往往是實(shí)現(xiàn)的隱喻,如果存在差異則會(huì)讓閱讀者看不懂代碼。
BadCode
// empty 的命名含義和實(shí)現(xiàn)截然相反 // (我真的見(jiàn)過(guò)這種代碼) function getProduct(id) { axios.delete("/product", {id}); }
GoodCode
function deleteProduct(id) { axios.delete("/product", {id}); }規(guī)則:對(duì)于布爾值的命名,需要默認(rèn)其為「真」
說(shuō)明:布爾變量的名稱(chēng)中,如果加上 「not」之類(lèi)的否定詞,則相當(dāng)于做了一次了邏輯判斷。
BadCode
const notEmpty = !!array.length;
GoodCode
const empty = !array.length;函數(shù) 規(guī)則:長(zhǎng)度不能超過(guò) 20 行
說(shuō)明:代碼太長(zhǎng)說(shuō)明做的事情不夠?qū)R唬瑫r(shí)也會(huì)讓閱讀變得很困難。
規(guī)則:Don"t repeat yourself說(shuō)明:同樣功能的代碼不要重復(fù)三次
規(guī)則:每個(gè)函數(shù)只做一件事情,并做好這件事說(shuō)明:代碼里的邏輯分支要盡量少,只做一件事情,并且要處理好邊界和異常情況。
規(guī)則:盡量減少函數(shù)的參數(shù),包括 opitons、config 等參數(shù)說(shuō)明:函數(shù)的輸入越多,往往就代表功能約復(fù)雜
規(guī)則:注釋出來(lái)項(xiàng)目/業(yè)務(wù)的坑說(shuō)明:對(duì)于比較奇怪的業(yè)務(wù)邏輯,或者因?yàn)橄到y(tǒng)、接口原因而寫(xiě)的比較奇怪的邏輯。要通過(guò)注釋標(biāo)注出來(lái)
BadCode
framework.doSomeThing(); framework.reset(); // 閱讀者內(nèi)心 OS:這里為啥要做一次 reset? framework.continueSomeThing();
GoodCode
framework.doSomeThing(); // framework 有個(gè) bug,這里必須要做一次 rest 附鏈接: http://github.com/issuse/*** framework.reset(); framework.continueSomeThing();規(guī)則:函數(shù)要盡量「純」沒(méi)有副作用
說(shuō)明:純函數(shù)比較好測(cè)試,邏輯也比較清晰,可以放心的引入和刪除。
BadCode
let status; function method() { if (status) { ... } }
GoodCode
function method(status) { if (status) { ... } }規(guī)則:函數(shù)最好不要修改參數(shù)內(nèi)的數(shù)據(jù)
說(shuō)明:修改參數(shù)會(huì)導(dǎo)致函數(shù)的作用變得不可預(yù)測(cè)
BadCode
function updateObj(obj, value) { obj.key = value; return obj; }
GoodCode
function updateObj(obj, value) { return {...obj, key: value}; }規(guī)則:除非是 class 的方法,否則不要訪問(wèn) this
說(shuō)明:this 的指向經(jīng)常不固定,會(huì)導(dǎo)致代碼難以理解。如果調(diào)用方不熟悉的話,很容易引起 Bug。
BadCode
function method() { console.log(this.value); } method() // 報(bào)錯(cuò) var obj = { method, value: 1} obj.method() // 輸出 1
GoodCode
function method(value) { console.log(value); }規(guī)則:處理錯(cuò)誤
說(shuō)明:錯(cuò)誤也是一種邏輯分支,如果不處理的話,代碼就不夠健壯。前端代碼處理錯(cuò)誤的方式一般為提示用戶有異常發(fā)生。如果錯(cuò)誤不影響業(yè)務(wù)流程,則寫(xiě)入日志里并上報(bào)。
BadCode
function method(data) { try { return JSON.parse(data) } catch (e) {} }
GoodCode
function method(data) { try { return JSON.parse(data) } catch (e) { alert("數(shù)據(jù)處理失敗") } }數(shù)據(jù) 規(guī)則:不要有 Magic Number
說(shuō)明:magic number 是指直接在代碼中硬編碼的數(shù)字,往往具有一些業(yè)務(wù)含義。
這樣會(huì)導(dǎo)致:
數(shù)字的意義難以理解
數(shù)值要改動(dòng)時(shí),要改很多地方
BadCode
if (status === 1) { ... } else if (type === 4) { ... }
GoodCode
enum Status { Closed } enum Type { Array } if (status === Status.Closed) { ... } else if (type === Type.Array) { ... }規(guī)則:不管是 react state 還是 vue data 存放的業(yè)務(wù)數(shù)據(jù)都要具備原子性。
說(shuō)明:原子性意味著獨(dú)立,且不可分割。其它屬性都由原子業(yè)務(wù)屬性推導(dǎo)、計(jì)算而來(lái),這樣能保證狀態(tài)的一致。
BadCode
// 當(dāng) status 為 open 的時(shí)候展示彈窗 // 其它狀態(tài)則隱藏彈窗 { data() { return { showAlert: false, status: "closed", } }, onStatusChange() { if (status === "open") { this.showAlert = true; } else { this.showAlert = false; } } }
GoodCode
// showAlert 為非原子的狀態(tài) // 其狀態(tài)可以由 status 推導(dǎo)而來(lái) { data() { return { status: "closed", } }, computed: { showAlert() { return this.status === "open"; } } }規(guī)則:對(duì)于 react state 和 vue data,應(yīng)當(dāng)區(qū)分業(yè)務(wù)狀態(tài)和 UI 狀態(tài)
說(shuō)明:
狀態(tài)和 UI 存儲(chǔ)在一起,有時(shí)候傳給后端的數(shù)據(jù)里會(huì)夾雜著沒(méi)有必要的 UI 狀態(tài)。
業(yè)務(wù)代碼和 UI 代碼耦合在一起,業(yè)務(wù)代碼沒(méi)法復(fù)用。
BadCode
// 在一個(gè)列表中,用戶可以對(duì)數(shù)據(jù)做多選 // 然后刪除他們 class extends React.Component { async componentDidMount() { const listData = getData(); this.setState({ listData }) } check = (item) => { const listData = this.state.listData.map(i => { if (i === item) { return {...item, checked: true} } return i; }); this.setState({ listData }); } delete() { // 返回給后端的數(shù)據(jù)結(jié)構(gòu),會(huì)多出一個(gè) checked 字段 deleteItems(this.state.listData.filter(i => i.checked)); } render() { const list = this.state.listData.map(item => { const className = ["item"]; if (item.checked) className.push("active"); return ; }); return <> {list} > } }
GoodCode
// 在一個(gè)列表中,用戶可以對(duì)數(shù)據(jù)做多選 // 然后刪除他們 class extends React.Component { async componentDidMount() { const listData = getData(); // 使用獨(dú)立的 selected 來(lái)保存 UI 狀態(tài) this.setState({ listData, selected: [] }) } check = (item) => { let { selected } = this.state; selected = selected.findOrInsert(s => s.id, item); this.setState({ selected }); } delete() { const { selected, listData } = this.state; deleteItems(listData.filter(i => selected.includes(i.id)))); } render() { const { selected, listData } = this.state; const list = listData.map(item => { const className = ["item"]; if (selected.includes(item.id)) className.push("active"); return ; }); return <> {list} > } }規(guī)則:對(duì)于 react 應(yīng)用,避免在 render 的時(shí)候修改狀態(tài)
說(shuō)明:react 的 render 應(yīng)該是純函數(shù),在 render 里運(yùn)行 setState 會(huì)導(dǎo)致重復(fù)渲染,或者死循環(huán)。
BadCode
// 如果 type 為 http 的話,則自動(dòng)轉(zhuǎn)換為 https class extends React.Component { render() { const { type } = this.state; if (type === "http") { this.setState({ type: "https"}) } return ; } }
GoodCode
// 如果 type 為 http 的話,則自動(dòng)轉(zhuǎn)換為 https class extends React.Component { get type() { const { type } = this.state; if (type === "http") return "https"; return type; } render() { const type = this.type; return ; } }規(guī)則:對(duì)于雙向綁定應(yīng)用,避免數(shù)據(jù)循環(huán)依賴(lài)。
說(shuō)明:
循環(huán)依賴(lài)輕則導(dǎo)致頁(yè)面相應(yīng)慢,重則導(dǎo)致出現(xiàn)臟數(shù)據(jù)。
避免循環(huán)依賴(lài)的前提是理清業(yè)務(wù)邏輯,搞清楚數(shù)據(jù)之間的依賴(lài)關(guān)系。
循環(huán)依賴(lài)也是雙向綁定技術(shù)的詬病之一。
BadCode
// foo 和 bar 互相依賴(lài),導(dǎo)致了死循環(huán) { data() { return { foo: 1, }; }, computed: { bar() { return this.foo + 1; } }, watch() { bar() { this.foo = this.bar + 1; }, } }規(guī)則:訪問(wèn)數(shù)據(jù)時(shí),需要考慮邊界情況和 JS 弱類(lèi)型的特性。
說(shuō)明:比如用雙等號(hào)做判斷
BadCode
const foo = "0"; const bar = 0 // 做數(shù)據(jù)判斷時(shí)不能用雙等號(hào) foo == bar // true foo ? 1 : 2 // 1 bar ? 1 : 2 // 2 // 僅通過(guò)變量有沒(méi)有 length 來(lái)判斷是否為數(shù)組 if(obj.length) { obj.forEach(...) }
GoodCode
const foo = "0"; const bar = 0 foo === bar // false if (Array.isArray(obj)) { obj.forEach(...) }規(guī)則:不要在遍歷數(shù)組的同時(shí),改變數(shù)組數(shù)據(jù)
說(shuō)明:這樣做會(huì)導(dǎo)致數(shù)據(jù)的異常。如果需要做這種操作,最好使用數(shù)組函數(shù),或者操作拷貝數(shù)據(jù)。
BadCode
const array = [1,2,3,4,5,6,7,8,9,10]; // 刪除數(shù)組中的偶數(shù) for (var i = 0; i < array.length; i++) { if (array[i] % 2 == 0) array.splice(i); } // array 變成了 [1]
GoodCode
const array = [1,2,3,4,5,6,7,8,9,10]; array.filter(a => !(a % 2))API 規(guī)則:對(duì) setTimeout 調(diào)用時(shí),傳遞的時(shí)間參數(shù)必須有意義。
說(shuō)明:
大多數(shù)場(chǎng)景下,setTimeout 后面?zhèn)鬟f一個(gè)時(shí)間是為了先執(zhí)行后續(xù)的 A 代碼,再延后執(zhí)行代碼閉包里的 B 代碼,如右邊示例代碼。
但如果隨著業(yè)務(wù)迭代,A 被改成異步,或者執(zhí)行時(shí)間很長(zhǎng)的話。之前做的延遲執(zhí)行的防御措施就時(shí)效了,也許反而 B 會(huì)比 A 先執(zhí)行。
BadCode
// 代碼的本來(lái)意圖是讓 B 延后執(zhí)行 setTimeout(() => { B(); }, 1000); A(); // 代碼的意圖是讓 render 在下一幀執(zhí)行 // 但是不同設(shè)備,一幀時(shí)間是不固定的 setTimeout(() => { render() }, 16);
GoodCode
// A 函數(shù)內(nèi)要想辦法使用 Promise 串接起來(lái) await A(); b(); // 使用系統(tǒng)提供的 API 執(zhí)行動(dòng)畫(huà)幀 requestAnimationFrame(() => { render(); });規(guī)則:不要使用陳舊的 API
說(shuō)明:陳舊的 API 往往有很多問(wèn)題,比如安全、性能、不易讀等。
BadCode
// 判斷是否為數(shù)組 Object.prototype.toString.call(array) === "[object Array]" // 查找數(shù)組里第一個(gè)偶數(shù) for (var i = 0; i < array.length; i++) { if (array[i] % 2 === 0) return array[i]; } // 遍歷對(duì)象的 key for (var key in obj) { console.log(key); } // 判斷字符串/數(shù)組是否包含 "some text".indexOf("some") >= 0 // 去除首位空格 " some text ".replace(/(^s+|s+$)/g, "") // 新建對(duì)象/數(shù)組 const array = new Array(); const obj = new Object();
GoodCode
Array.isArray(array) array.find(a => a % 2 === 0); Object.keys(obj).forEach(console.log) "some text".includes("some") " some text ".trim() const array = []; const obj = {};規(guī)則:對(duì)于 99.9% 的場(chǎng)景,你都不需要使用 React ref
說(shuō)明:
React Ref 一般是用來(lái)處理和原生 DOM 交互的場(chǎng)景,比如 canvas。
大部分對(duì)于 React ref 的使用都是錯(cuò)誤的,大多都拿來(lái)用來(lái)控制子元素。這種場(chǎng)景我們更推薦用數(shù)據(jù)流(redux,mobx)或者用狀態(tài)提升去做。
React 官方有對(duì)「狀態(tài)提升」的描述 https://react.docschina.org/d...
BadCode
class List extends React.Component { async refresh() { this.setState({ items: getItems(), }); } render() { return this.state.items.map(i => ); } } class extends React.Component { onRefresh = () => { // 用 ref 去調(diào)用子元素的方法 this.list.refresh(); } render() { return <>this.list = l}>
GoodCode
class List extends React.Component { render() { return this.props.items.map(i => ); } } class extends React.Component { // 把數(shù)據(jù)狀態(tài)提升到父組件做操作 refresh = async () => { this.setState({ items: getItems(), }); } render() { return <>規(guī)則:不要用字符串拼接 url
說(shuō)明:
字符串拼接 url 需要處理 encode 或者 decode 的情況,還有對(duì)于 ?和 # 的判斷不對(duì)的話,很容易造成漏洞或者 Bug。
目前瀏覽器和 Node 都已經(jīng)提供了標(biāo)準(zhǔn)的 URL 解析方法。
https://developer.mozilla.org...
BadCode
// 這段代碼既沒(méi)有對(duì) key、value 做 encode // 也沒(méi)有考慮 url 中 # 出現(xiàn)的情況 const url = location.href; if (url.indexOf("?") >= 0) { return url + key + "=" + value; } else { return url + "?" + key + "=" + value; }
GoodCode
// 使用標(biāo)準(zhǔn)的 URL 解析,風(fēng)險(xiǎn)會(huì)降低很多 const url = new URL(urlStr); url.searchParams.set(key, value); return url.toString();邏輯 規(guī)則:判真不判假
說(shuō)明:
我們應(yīng)該期望 if 條件內(nèi)是個(gè)「真」值,而不是一個(gè)「假」值。
第二種情況會(huì)導(dǎo)致代碼不易理解。
解決辦法參考 布爾邏輯
BadCode
// if 條件內(nèi)期望的是一個(gè)「假」值 if (!(status !== Closed) { ... } if (!(status !== Closed || type !== Array)) { ...}
GoodCode
if (status === Closed) { ... } if (status === Closed && type === Array) { ... }規(guī)則:if 條件中,不易出現(xiàn)超過(guò) 3 個(gè)邏輯操作符。
例外:if 條件里可以被 「且」(&&)邏輯拆分成多個(gè)子條件
說(shuō)明:復(fù)雜的條件判斷會(huì)讓代碼不易理解,邏輯上有漏洞的話容易引起 Bug。
解決辦法:聲明中間變量
BadCode
if (srcElem != dropElem && (srcElem.nextSibling || srcElem.nextElementSibling) != dropElem) {...} if (selectedItem || (selectedEmployee && selectedEmployee.empId && selectedEmployee) || employee) { ... }
GoodCode
const nextSibling = srcElem.nextSibling || srcElem.nextElementSibling if (srcElem != dropElem && nextSibling != dropElem ) { ... } // 復(fù)雜的邏輯判斷可以通過(guò) && 做拆分 if ( !Array.isArray(cur) && cur != null && typeof src[key] === "object" && typeof cur === "object" ) { ... }規(guī)則:不要用嵌套的三元表達(dá)式
說(shuō)明:
人們閱讀嵌套三元表達(dá)式時(shí),容易混淆語(yǔ)法的優(yōu)先級(jí),進(jìn)而導(dǎo)致理解錯(cuò)代碼的含義。
對(duì)于這種情況,建議改成 if else。
如果是在 react render 里,則建議獨(dú)立成函數(shù)。
BadCode
function render(props) { const value = props.value; return <> {value < 10 ? value > 0 ? value : 200 - value : 100 - value} >; }
GoodCode
function getValue(value) { if (value < 10) { if (value > 0) return value; return 200 - value; } return 100 - value; } function render(props) { const value = props.value; return <> {getValue(value)} >; }規(guī)則:if 條件邏輯嵌套不要超過(guò)三層
說(shuō)明:過(guò)深的嵌套會(huì)導(dǎo)致理解困難。
解決辦法:合并判斷條件,或者獨(dú)立成函數(shù)。
BadCode
if (status = Opened) { if (type = "array") { if (code = Success) { doSomething(); } } }
GoodCode
if (status = Opened && type = "array" &&code = Success) { doSomething(); }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109295.html
摘要:虛擬代理虛擬代理把一些開(kāi)銷(xiāo)很大的對(duì)象,延遲到真正需要它的時(shí)候才去創(chuàng)建。主要參考設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐 設(shè)計(jì)模式 在面向?qū)ο筌浖O(shè)計(jì)過(guò)程中針對(duì)特定問(wèn)題的簡(jiǎn)潔而優(yōu)雅的解決方案。 這是在《設(shè)計(jì)模式》一書(shū)中對(duì)設(shè)計(jì)模式的定義。在軟件開(kāi)發(fā)過(guò)程中,我們可能會(huì)遇到過(guò)這樣的情況,我們現(xiàn)在發(fā)現(xiàn)一個(gè)問(wèn)題,和以前的某個(gè)問(wèn)題很相似,幾乎可以用統(tǒng)一套解決方案,而且我們還發(fā)現(xiàn),在某個(gè)條件下,這個(gè)解決方案幾乎就是通用的,...
摘要:所以這中間需要一個(gè)取舍,哪些是要嚴(yán)格要求的,哪些是可以不管的。首先,好代碼可能是聊出來(lái)的。比如需求確認(rèn)這一塊,多問(wèn)多畫(huà)流程圖少動(dòng)手。在這個(gè)過(guò)程中不斷整理和梳理原有的概念。代碼的直接修改。最后,好代碼是改出來(lái)的。 作為前端負(fù)責(zé)人,很多時(shí)候發(fā)愁的不是寫(xiě)好代碼,而是怎么讓身邊水平較差的小伙伴能寫(xiě)出好的代碼 另外,你還要保證項(xiàng)目的進(jìn)度,所以代碼質(zhì)量和項(xiàng)目進(jìn)度之間有著天然的矛盾,怎么去平衡值得我...
摘要:所以這中間需要一個(gè)取舍,哪些是要嚴(yán)格要求的,哪些是可以不管的。首先,好代碼可能是聊出來(lái)的。比如需求確認(rèn)這一塊,多問(wèn)多畫(huà)流程圖少動(dòng)手。在這個(gè)過(guò)程中不斷整理和梳理原有的概念。代碼的直接修改。最后,好代碼是改出來(lái)的。 作為前端負(fù)責(zé)人,很多時(shí)候發(fā)愁的不是寫(xiě)好代碼,而是怎么讓身邊水平較差的小伙伴能寫(xiě)出好的代碼 另外,你還要保證項(xiàng)目的進(jìn)度,所以代碼質(zhì)量和項(xiàng)目進(jìn)度之間有著天然的矛盾,怎么去平衡值得我...
摘要:所以這中間需要一個(gè)取舍,哪些是要嚴(yán)格要求的,哪些是可以不管的。首先,好代碼可能是聊出來(lái)的。比如需求確認(rèn)這一塊,多問(wèn)多畫(huà)流程圖少動(dòng)手。在這個(gè)過(guò)程中不斷整理和梳理原有的概念。代碼的直接修改。最后,好代碼是改出來(lái)的。 作為前端負(fù)責(zé)人,很多時(shí)候發(fā)愁的不是寫(xiě)好代碼,而是怎么讓身邊水平較差的小伙伴能寫(xiě)出好的代碼 另外,你還要保證項(xiàng)目的進(jìn)度,所以代碼質(zhì)量和項(xiàng)目進(jìn)度之間有著天然的矛盾,怎么去平衡值得我...
閱讀 2313·2021-11-08 13:13
閱讀 1244·2021-10-09 09:41
閱讀 1682·2021-09-02 15:40
閱讀 3185·2021-08-17 10:13
閱讀 2545·2019-08-29 16:33
閱讀 3121·2019-08-29 13:17
閱讀 3130·2019-08-29 11:00
閱讀 3295·2019-08-26 13:40