Preamble: The next step is to open up a small volume of knowledge about best practices for applets, which are used as a starting point, but by no means limited to this. There will be several chapters “Naming,” “Single Test,” “Code Style,” “Comments,” “Safe Production,” “Refactoring,” “Code Design,” “Performance,” “Internationalization,” and “Why Applets Development Best Practices.” Each will contain positive and negative examples and detailed explanations.
The examples in this article are typical problems found during CR. Hopefully, you will be able to avoid such problems in advance with this booklet and focus our CR more on business logic rather than such trivialities or lack of basic ideas, resulting in a high quality CR.
Named article ✍ 🏻
It’s proven that we spend more time reading code than we do writing it, so good naming always pays off in the future.
Principle 1: Readability Counts
Rule of brevity: If English has multiple words, be sure to choose the most “approachable”, not so obscure that you need to look up the dictionary.
Bad
In an application where the user wants to cancel the withholding, the product sets the button text as “still want to close” rather than “unsubscribe” in order to retain the user. The developers name the event callback onRescission, based on its very definition.
<button . onClick="onRescission">Still want to close</button>
Copy the code
Good
Name it onUnsubscribeBtnClick, a more common word, and use unsubscribe for the withholding scenario to better reflect its business attributes of subscribing and unsubscribing.
<button . onClick="onUnsubscribeBtnClick">Still want to close</button>
Copy the code
Principle 2: Be semantic
Semantic principle: Meaningful business attribute naming is better than vague and broad naming. Loosely named is equivalent to no name at all.
Bad
Data, process, handle, and flag as bool are all bad names.
Good
data
= >bank
(bank)process
= >addBankNamePostfix
(Add bank card suffix)handle
= >onCardClick
(Bank card click event)flag
= >isDebtCard
(Whether it is a debit card)
💡 Tips: Learn how to name well-known libraries in the industry.
Principle 3: Complementary principle
Using antithesis vocabulary to reduce the cost of understanding can significantly reduce code complexity. Commonly used antithesis words:
The verb
get | set |
---|---|
add | remove |
create | destroy |
start | stop |
begin | end |
insert | delete |
show | hide |
suspend | resume |
lock | unlock |
open | close |
on | off |
subscribe | unsubscribe |
noun
first | last |
---|---|
increment | decrement |
min | max |
next | previous |
source | destination |
src | dest |
soure | target |
Adjective or adverb
old | new |
---|---|
active | inactive |
visible | invisible |
up | down |
From the code clean way andC++ Programming Style Guidelines.
Not Good
AnotherTab outside of the click state is called anotherTab, which is still a bit less interesting 🤔.
const anotherTabTaskId = tabs[activeTab === 0 ? 1 : 0]? .taskId;Copy the code
Good
The antithesis of active is inactive, the cost of understanding drops instantly 👍
const inactiveTabTaskId = tabs[activeTab === 0 ? 1 : 0]? .taskId;Copy the code
Bad
{
/** * the "View bill" button is exposed */
onBillListBtnShow() {
tracert.expo(withdrawResultSpms.viewBill.expo);
},
/** * click "View bill" */
onOpenUrl(){ openPage(WITHDRAW_BILL_LIST_URL); }},Copy the code
<! -- Check the bill -->
<view onTap="onOpenUrl" onAppear="onBillListBtnShow">.</view>
Copy the code
Good
OnOpenUrl is changed to onBillListBtnClick, as opposed to onBillListBtnShow, making it easy for readers to make a connection between the two.
{
onBillListBtnShow() {
tracert.expo(withdrawResultSpms.viewBill.expo);
},
onBillListBtnClick(){ openPage(WITHDRAW_BILL_LIST_URL); }},Copy the code
<view onTap="onBillListBtnClick" onAppear="onBillListBtnShow">.</view>
Copy the code
The function name
Principle 1: Verb-object structure
Functions are used to process data or perform a procedure, so they must conform to doSth’s verb-object structure. If the context is clear enough, the object can be omitted and only the verb used.
Bad
Account class desensitization method, named accountDesensitization, in violation of the object principle.
function accountDesensitization() {
// ...
}
Copy the code
Good
The name desensitizeAccount conforms to the verb-object structure.
function desensitizeAccount() {
// ...
}
Copy the code
Better
Named mask, more concise, not unusual, with metaphor more image more understandable, because desensitization is actually cover most of the characters, only exposed part of the characters, such as mobile phone number desensitization 18157061234, retain the first three after two become 181******34.
function mask() {
// ...
}
Copy the code
Note: desensitization of the client is not recommended. If the front end accepts such requirements, it can desensitize the back end or BFF layer for security reasons, and please use the company’s unified desensitization SDK.
Principle 2: Event callback uniform prefix
Event callbacks start with on or Handle, consistent within the project, such as onSthClick handleSthClick.
Bad
TargetToCouponAll violates this specification.
<button onClick="targetToCouponAll">.</button>
Copy the code
Good
TargetToCouponAll = > onCouponCenterClick.
<button onClick="onCouponCenterClick">.</button>
Copy the code
Principle 3: Naming conventions for functions that return Boolean values
It usually starts with is/has/can/should, such as shouldComponentUpdate for React.
// Function that returns a Boolean value
function isVisible() :boolean;
function hasLicense() :boolean;
function canEvaluate() :boolean;
function shouldSort() :boolean;
Copy the code
Principle 4: Function naming abstraction principle
Function names should be abstract, meaning that implementation details need to be hidden. The function name is the interface (API), the interface is a black box, so the name needs to be abstract.
Bad
This function is intended to sort a certain set, group is just a means of sorting or implementation details, should hide the underlying implementation details, and later reconstruction does not use group to change to a better algorithm, whether the function name should be changed? Second, the word data is very broad, without any specific meaning, and does not reflect the attributes of its collection. This function is not a general sorting function, so it is suggested to use a name with more business attributes.
function sortAndGroupData(data) {
// ...
}
Copy the code
Good
SortPromotionTasks only illustrate their sorting ability, and do not expose nor need to expose the sorting details, in accordance with the “least knowledge principle”.
/** * Order marketing tasks according to xx rules *@param tasks
*/
function sortPromotionTasks(tasks) {}Copy the code
Variable naming
General variable naming
A regular variable should be a noun, should not carry a type, abstract rather than concrete, otherwise it will cause “abstraction leakage”, in other words change the variable type, all use needs to change. See below for other naming rules.
Rule 1: A variable should be a noun
Bad
/** Target link */
const goPage = 'https://www.example.com/'
Copy the code
GoPage violates the naming convention, doSth is the function naming convention.
Good
/** Target link */
const targetUrl = 'https://www.example.com/'
Copy the code
Rule two: Names should not carry types
Bad
IResultObj does not require the type suffix Obj.
interface IResultObj {
success: boolean;
};
Copy the code
Good
interface IResult {
success: boolean;
};
Copy the code
Boolean variable
There was a case in 2020 where a large number of apps using the Facebook SDK crashed, with the code naming question “Why would a dictionary structure have an obvious Boolean name like is_health_app?” For details, see Facebook SDK leading to the collapse of mainstream Apps in Europe and America.
Boolean variable naming, using adjectives and tenses: able/ible/ing/Ed. For example: Visible maintaining finished found.
Bad
let imgDisable
let isTipsVisible // isXXX is usually used for function naming.
let showTips // showTips is a verb-object structure and a function name. It is not recommended to name it as a Boolean value
let canCollectTaskCard // Pick up the task
Copy the code
Good
let imgDisabled = false;
let tipsVisible;
// Collectible, ible ending in ability to "be xx"
let collectable;
Copy the code
The enumeration name
Enumeration class names are suffixed with enums. Enumerator names must be all uppercase and separated by underscores (_).
No compulsion, just follow the company’s specifications.
Note: Enumerations are simply special constant classes, and the constructor is forced to be private by default.
Good
The process name is ProcessStatusEnum, and the member name is SUCCESS/UNKNOWN_REASON.
const enum ProcessStatusEnum {
SUCCESS = 100,
UNKNOWN_REASON = 200,}Copy the code
The interface name
The TS interface must be prefixed with I
Interfaces or types, such as ILbs, are intended to be distinguished from classes.
export interface ILbs {
city: string;
cityAdcode: string;
longitude: string;
latitude: string;
}
Copy the code
Secondly, the interface name must have biz specificity
Service features are available.
Bad
The input parameter IObjParamInterface is too broad, but is really only used by one function.
export function mask(objParam: IObjParamInterface) :string {}interface IObjParamInterface {
str: string; startNum? :number; lastNum? :number;
formatStr: string;
}
Copy the code
Good
Add the function name IMaskOptions to make it more specific.
export function mask(options: IMaskOptions) :string {}interface IMaskOptions {
str: string; startNum? :number; lastNum? :number;
formatStr: string;
}
Copy the code
Request return value and parameter name
[Suggestion] : Start with I + service feature + Resp, so that you can know that this is the return value type, similarly request parameters end with Req.
Good
interface IParkingFeeResp {}
interface IParkingFeeReq {}
Copy the code
Constant named
For a series of equivalent or related constants, the last word is usually used to distinguish its state or purpose, so that the specification can be neatly extended to various states.
For example, application state naming:
Not Good
const APP_MAINTENANCE_STATUS = 1; / / maintenance
const APP_RUNNING_STATUS = 2; // It is running properly
Copy the code
Good
It’s much more visually tidy, with emphasis on the end, so it’s easier for the naked eye to pick up the difference.
const APP_STATUS_MAINTAINING = 1;
const APP_STATUS_IN_SERVICE = 2;
Copy the code
The CSS class name
- Class is a descriptive state. It should be an adjective or a noun. Please refer to the well-known CSS component libraries such as ANTD and Bootstrap.
- Abstract principle, naming does not expose the underlying implementation, more conducive to later extension. Naming is an interface, and interfaces need to be abstracted.
- Do not include styles, such as positioning (margin, left, right, center) or color (blue), otherwise the style will change the class name later.
- [Suggestion] Delimit by a hyphen
- Component root node name
{component name}-wrapper
If the CSS Module is not used, the name is used to avoid conflicts{component name}-usage
.
Bad
Improper naming: In baton-info-center, center is the style, and the naming and style are coupled, resulting in a lack of scalability. What if it is not centered in the future?
<view class="coupon-info-center"></view>
Copy the code
Good
Baton-info-center => baton-title-only Because the probability of style change is much greater than that of business logic, if the style is changed, you only need to modify the CSS.
<view class="coupon-title-only"></view>
Copy the code
The plural named
Collection naming rules.
- Countable noun addition
s
, such as cards
, items
- Uncountable noun plus
List
, for example, extra => extraList
- How to name a two-dimensional array: countable noun contact
sList
Uncountable noun extraLists
Bad
const imagelist = JSON.parse(getIn(item, [ 'extInfos'.'imagelist'].'[]'));
Copy the code
Good
‘image’ is a countable noun, so ‘images’ is more concise.
const images = JSON.parse(getIn(item, [ 'extInfos'.'imagelist'].'[]'));
Copy the code
Bad
The ActivityStatusEnumArr suffix Arr determines that the underlying data structure must be data and does not extend.
export const ActivityStatusEnumArr = [
'ON'.'OFF',]Copy the code
Good
export const activityStatusList = [
'ON'.'OFF',]Copy the code
Storage field naming
Key is a special class of constants that need to be distinguished from other constants to prevent collisions:
- Store key naming conventions to
STORAGE_KEY
Beginning, distinct from regular constants, format:STORAGE_KEY_${BIZ_KEY}
- Example: Last shutdown time hint:
STORAGE_KEY_TIPS_LAST_CLOSED_TIME
- Example: Last shutdown time hint:
- All stored fields are unified into a common constant file management, preventing conflicts, and reducing duplicate prefixes through namespace
Bad
Each page defines its own key that can easily be overwritten or read into the stored content of other pages.
// page/index/index.ts
const TIPS_LAST_CLOSED_TIME = 'TIPS_LAST_CLOSED_TIME';
Copy the code
Good
Unified to a constant file, standard management.
// src/common/constants.ts
export const STORAGE_KEY_TIPS_LAST_CLOSED_TIME = 'TIPS_LAST_CLOSED_TIME';
export const STORAGE_KEY_UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME
= 'UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME'
Copy the code
Better
Save key length with namespace STORAGE_KEYS context.
// src/common/constants/storage-keys.ts
export const STORAGE_KEYS = {
tipsLastClosedTime: 'TIPS_LAST_CLOSED_TIME'.uncertifiedPromotionTipsLastClosedTime: 'UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME',}Copy the code
Page, component names
[Suggestion] The page should be presented as a verb or a noun, and the component should be a noun.
Good
The page can be named after a verb or a noun
SRC /pages ├─ Car-moving-code-apply └─ discovery // discovery Noun formCopy the code
Components are named with nouns
├─ exercises ├─ car-moving-code-expression-card ├─ mt-store-list.htm // Exercises ├─ car-moving-code-Expression-card ├─ mt-store-list.htmCopy the code