no.56, avoid unnecessary state
Tips:
- Use stateless APIs as much as you can
- If the API is stateful, indicate which states are associated with each operation
The stateless API is simple, easier to learn and use, and does not need to be considered in other states. Such as:
‘test‘.toUpperCase(); // ‘TEST‘
Stateful APIs tend to cause additional claims and increase complexity.
no.57, design flexible interfaces using structural types
Tips:
- Design flexible object interfaces using struct types (also known as duck types)
- Structure interfaces are more flexible and lightweight, so you should avoid using inheritance
- For unit testing, the use of mock objects, the alternative implementation of interfaces, to provide a reusable behavior
Directly on the code:
function Wiki(format){ this.format = format;}Wiki.prototype.show = function(source){ var page = this.format(source); return { title: page.getTitle(), author: page.getAuthor(), content: page.getContent() }}
Designing format as a structure type can greatly increase the flexibility of your design.
no.58, area fractional group objects, and class array objects
Tips:
- Never overload a struct type that has overlapping other types
- When you overload a struct type with another type, test other types first
- Receive true arrays instead of class array objects when other object types are overloaded
APIs should never overload types that overlap other types
The simplest array of judgments and arrays of classes, the code is as follows:
x instanceof Array
However, in some environments where multiple global objects are allowed, there may be multiple copies of the standard array constructor and prototype objects. Then it is possible to cause the above test results to be untrusted, so the Array.isarray function is introduced in ES5 to determine whether an array object is determined by checking whether the [[Class] property value inside the object is an array. In an environment that does not support ES5, you can use the standard Object.prototype.toString method to test whether an object is an array.
function isArray(x){ return toString.call(x) === ‘[object Array]‘;}
no.59, avoid excessive coercion
Tips:
- Avoid the mixing of casts and overloads
- Consider defensive monitoring of unexpected inputs
Look at the following functions:
function square(x){ return x*x;}console.log(square(‘3‘));
Casting is undoubtedly very convenient. But many times it can lead to ambiguity.
function fun(x){ x = Number(x); if(typeof x === ‘number‘){ return x-1; }else{ return x; }}
Because number (x) is being carried out, the subsequent else cannot be executed. If you do not know the details of this function, then using this function has a certain degree of ambiguity. In fact, if we were to design the API more carefully, we could force only the numbers and objects to be accepted.
function fun(x){ if(typeof x === ‘number‘){ return x-1; }else if(typeof x === ‘object‘ && x){ return x; }else{ throw new TypeError(‘expected number or array-like.‘); }}
A more cautious example of this style is known as defensive programming.
No.60, support method chain
Tips:
- Using a method chain to connect stateless operations
- Support for method chains by returning new objects in a stateless method
- Supports the method chain by returning this in a stateful method
The stateless API part capability is to speak of complex operations that decompose into smaller operations. such as replace:
function escapeHtml(str){ return str.replace(/&/g, ‘&‘) .replace(/</g, ‘<‘);}
If you do not use a method chain, the code should be the following:
function escapeHtml(str){ var str1 = str.replace(/&/g, ‘&‘); var str2 = str1.replace(/</g, ‘<‘); return str2;}
The same functionality will result in multiple temporary variables. Eliminating temporary variables makes the code more readable, and intermediate results are just one important step in the final result.
It is also possible to set up a method chain in a stateful API. The trick is that the method returns this when the object is updated, rather than undefined. Such as:
element.setBackgroundColor(‘gray‘) .setColor(‘red‘) .setFontweight(‘bold‘);
68 Effective ways to write high-quality JS code (12)