The topic of “code specification” has always been a topic of interest, and there have even been a lot of jokes about it in the industry. Since code specifications have such resonance, today we’ll talk about the self-cultivation of a programmer — how to write elegant code?
First, interface fluency
A good interface is smooth and easy to understand, which mainly reflects the following aspects:
- simple
To manipulate the CSS properties of an element, here is the native method:
document.querySelectorAll('#id').style.color = 'red';
Copy the code
After the encapsulation
function a(selector, color) {
document.querySelectorAll(selector)[0].style.color = color
}
a('#a'.'red');
Copy the code
From a line of dozens of letters to a simple function call, the API is simple and easy to use
- Reading can be
A (‘ #a ‘, ‘red’) is a nice function that allows us to change an element in a simple and practical way, but the problem is that if you’re using a function for the first time, it’s confusing. It is important to know that people are lazy. For example, the color assignment function, although less code is written, but increased memory costs. You have to have a mapping every time you do this. A — >color. If it is simple, it doesn’t matter, but usually a set of frameworks have dozens or even hundreds of apis, and the increased cost of mapping will cause programmers to crash. All we need is for the interface to make sense, so let’s rewrite the a function:
function letSomeElementChangeColor(selector, color) {
document.querySelectorAll(selector, color);
}
Copy the code
LetSomeElementChangeColor relative to a given language meaning, everyone know its meaning
- Reduce memory costs
We just function is that it’s too long letSomeElementChangeColor while reducing the cost of mapping, but increased the cost of memory. You know, no one, not even top students, likes to be called words. The primary access to the dom API is also have the problem of the document. The getElementsByClassName; document.getElementsByName; document.querySelectorAll; The API feels like the words are too long, and while the meaning is clear, this is done at the expense of simplicity. So let’s rewrite this function again
function setColor(selector, color) {
// ...
}
Copy the code
Shorten the function name without making a big change in meaning. Make it easy to read, remember and use;
- Extension,
By extension, we mean that the use of functions is executed in written order like a flow of water to form a chain of execution:
document.getElementById('id').style.color = 'red';
document.getElementById('id').style.fontSize = '12px';
document.getElementById('id').style.backgourdColor = 'pink';
Copy the code
The way we did it before the way we did it before was to encapsulate two functions again setFontSize, setbackgroundColor; Then execute them setColor(‘ id ‘, ‘red’); SetFontSiez (” id “, “12 px”); SetbackgroundColor (” id “, “pink”); Obviously, this approach is not lazy out of the realm; The ID element needs to be retrieved each time, affecting performance and failing; Every time I have to add a new method and it fails and every time I call those methods, it fails again. We’ll rewrite it as an extendable function that first encapsulates the method that gets the ID as an object, and then returns the object in each of the object’s methods:
function getElement(selector) {
this.style = document.querySelecotrAll(selector).style;
}
getElement.prototype.color = function(color) {
this.style.color = color;
return this;
}
getElement.prototype.background = function(bg) {
this.style.backgroundColor = color;
return this;
}
getElement.prototype.fontSize = function(size) {
this.style.fontSize = size;
return this;
}
/ / call
var el = new getElement('#id')
el.color('red').background('pink').fontSize('12px');
Copy the code
Simple, smooth, easy to read and we’ll talk about how to continue optimizing in parameters later. As a result, people prefer to use the jquery API, although a $symbol does not mean anything, but the simple symbol is good for us to use. It embodies the above a variety of principles, simple, easy to read, easy to remember, chain writing, multi-parameter processing.
The bad:
document.getElementById('id').style.color = 'red';
document.getElementById('id').style.fontSize = '12px';
document.getElementById('id').style.backgourdColor = 'pink';
Copy the code
Expectations:
$('id').css({color:'red'.fontSize:'12px'.backgroundColor:'pink'})
Copy the code
Ii. Consistency
- Interface consistency
The associated interfaces remain consistent in style, and a suite of apis, if delivered with a sense of familiarity and comfort, can greatly ease developers’ adaptability to new tools. “There are only two headaches in computer science: cache invalidation and naming problems” — Phil Karlton pick a phrase you like and stick with it. Pick a style and stay that way.
The bad:
setColor,
letBackGround
changefontSize
makedisplay
Copy the code
Expectations:
setColor;
setBackground;
setFontSize
set.........
Copy the code
Keep your code style and naming style as much as possible so that people read your code as if it were written by the same person.
Third, the balance
The next principle is balance, where elements are organized so that one part is not so heavy that it overshadows the other and is used in an unstable manner. In art, balance is visual weight. Even if it is asymmetrical, there is still a sense of balance in the work because it follows a pattern. The balance of API design in context, I refer specifically to the visual weight and predictability of the code.
Balanced apis give the impression that their components belong to each other, that they act the same, or complement each other to accomplish a goal. APIs can also feel balanced by extension, allowing developers to easily predict other APIs and use them. Like Modernizr’s property tests, they are balanced in two ways: a) property names correspond to HTML5 and CSS terms and API names, and b) each property test uniformly returns true or false values.
Modernizr.geolocation
Modernizr.localstorage
Modernizr.webworkers
Modernizr.canvas
Modernizr.borderradius
Modernizr.boxshadow
Modernizr.flexbox
Copy the code
Accessing a single property tells the developer what they need to know about the property in order to access every other property. The power of a quality API is its simplicity. Balance also ensures that the code I write to interact with Modernizr has the same visual weight every time I read and write. How TO look and feel the same when I use and access the API, regardless of my conventions. On the other hand, if Modernizr added a Polyfill Canvas API, not only would the visual weight of the library be affected by the new API, Modernizr’s scope and use would be greatly expanded, and my predictability would be limited when I interact with the API.
Another way to achieve balance is by relying on the developer’s familiarity with the concept for predictable results. A typical example is jQuery’s selector syntax, which maps cSS1-3’s selector to its own DOM selector engine:
$("#grid") // Selects by ID
$("ul.nav > li") // All LIs for the UL with class "nav"
$("ul li:nth-child(2)") // Second item in each list
Copy the code
By using a familiar concept and mapping it to its own library, jquery avoids the new selector syntax and creates a mechanism for new users to quickly apply the library to production via a predictable API.
4. Processing of parameters
- Parameter type
Determining the type of argument provides stability for your program
// We specify that color accepts strings
function setColor(color) {
if(typeofcolor ! = ='string') return;
/ /.. dosomething
}
Copy the code
- Pass parameters in JSON mode
Using JSON to pass values has many advantages. It allows you to name parameters, ignore their location, and give them default values.
function fn(param1, param2............... paramN)
Copy the code
You must pass each argument in the correct order, otherwise your method will not execute as expected. The correct way to do this is as follows.
function fn(json) {
// Set default values for required parameters
var default = extend({
param: 'default'.param1: 'default'
// ...
}, json)
}
Copy the code
This function code is expected to run even if you pass no arguments. Because at declaration time, you will determine the default value of the parameter according to the specific business.
5. Scalability
One of the most important principles of software design: never modify an interface, just extend it! Extensibility also requires an interface to have a single responsibility, which makes it difficult to extend an interface with multiple responsibilities. Here’s an example:
You need to change both the font and the background of an element
The bad:
function set(selector, color) {
document.querySelectroAll(selector).style.color = color;
document.querySelectroAll(selector).style.backgroundColor = color;
}
Copy the code
There is no way to extend the resize function. If you need to change the font size again, you can only modify the function by adding the code to change the font size
Expectations:
function set(selector, color) {
var el = document.querySelectroAll(selector);
el.style.color = color;
el.style.backgroundColor = color;
return el;
}
Copy the code
You need to set the font, background color, and size
function setAgain (selector, color, px) {
var el = set(selector, color)
el.style.fontSize = px;
return el;
}
Copy the code
The above is simply adding color. When the business is complex and the code is not yours to write, you have to read the previous code and change it, which is clearly not open and closed. The modified function returns the element object so that it can be processed again the next time it needs to be changed.
- The use of this
Extensibility also includes flexible use of the this and call and apply methods:
function sayBonjour() {
alert(this.a)
}
obj.a = 1;
obj.say = sayBonjour;
obj.say();/ / 1
//or
sayBonjour.call||apply(obj); / / 1
Copy the code
Six, the handling of errors
- See error
You can use type to detect typeof or try… The catch. Typeof forces detection objects not to throw errors, especially useful for undefined variables.
- Throw an error
Most developers don’t want to have to find the correct code if something goes wrong, and the best way to do that is to print it directly to the console and tell the user what happened. We can use the browser output API: the console log/warn/error. You can also leave some options open for your own programs: try… The catch.
function error (a) {
if(typeofa ! = ='string') {
console.error('param a must be type of string')}}function error() {
try {
// some code excucete here maybe throw wrong
}catch(ex) {
console.wran(ex); }}Copy the code
7. Predictability
Predictability provides robustness. In order for your code to execute smoothly, it must allow for unexpected situations. So let’s look at the difference between unpredictable code and predictable code using setColor
The bad:
function set(selector, color) {
document.getElementById(selector).style.color = color;
}
Copy the code
Expectations:
zepto.init = function(selector, context) {
var dom
// If nothing given, return an empty Zepto collection
if(! selector)return zepto.Z()
// Optimize for string selectors
else if (typeof selector == 'string') {
selector = selector.trim()
// If it's a html fragment, create nodes from it
// Note: In both Chrome 21 and Firefox 15, DOM error 12
// is thrown if the fragment doesn't begin with <
if (selector[0] = ='<' && fragmentRE.test(selector))
dom = zepto.fragment(selector, RegExp. $1, context), selector = null
// If there's a context, create a collection on that context first, and select
// nodes from there
else if(context ! = =undefined) return $(context).find(selector)
// If it's a CSS selector, use it to select nodes.
else dom = zepto.qsa(document, selector)
}
// If a function is given, call it when the DOM is ready
else if (isFunction(selector)) return $(document).ready(selector)
// If a Zepto collection is given, just return it
else if (zepto.isZ(selector)) return selector
else {
// normalize array if an array of nodes is given
if (isArray(selector)) dom = compact(selector)
// Wrap DOM nodes.
else if (isObject(selector))
dom = [selector], selector = null
// If it's a html fragment, create nodes from it
else if (fragmentRE.test(selector))
dom = zepto.fragment(selector.trim(), RegExp. $1, context), selector = null
// If there's a context, create a collection on that context first, and select
// nodes from there
else if(context ! = =undefined) return $(context).find(selector)
// And last but no least, if it's a CSS selector, use it to select nodes.
else dom = zepto.qsa(document, selector)
}
// create a new Zepto collection from the nodes found
return zepto.Z(dom, selector)
}
Copy the code
The above is the source code for Zepto, and you can see that the author did a lot of work in anticipating the incoming parameters. In fact, predictability provides a number of entry points to the program, and is nothing more than logical judgment. Zepto uses a lot of right and wrong judgment here, which leads to long, unreadable code. Anyway, predictability is really what you need to do is write a lot of parameters to the location of the object. Change external detection to internal detection. Yes, people who use it are comfortable, relieved and happy. Shout! As a human being, the most important thing is Haysen.
8. Readability of comments and documents
One of the best interfaces is one that we use without documentation, but it can be a bit of a struggle when there are more interfaces and more business. So interface documentation and comments need to be carefully written. Notes follow the principle of simplicity and conciseness, both for yourself and for those who will follow you years from now:
// Comment interface for powerpoint presentation
function commentary() {
// If you define a variable that has no literal meaning, it is best to comment it: a: Useless variables can be deleted
var a;
// Add comments to key and ambiguous areas as a finishing touch: after routing to the hash interface, clear all data from the end function
return go.Navigate('hash'.function(){
data.clear();
});
}
Copy the code
Article reference: sell barbecue sky
The last
- Please follow me on GitHub for more content
- It’s hard to be original. Give it a thumbs up.
- Welcome to pay attention to the public number “front-end advanced class” seriously learn the front end, step up together.