In-depth analysis of JavaScript API design principles (reproduced)

Source: Internet
Author: User

First, the flow of the interface

The good interface is smooth and easy to understand, he mainly embodies the following aspects:

1. Simple

To manipulate the CSS properties of an element, here is the native method:

?
1 document.querySelectorAll(‘#id‘).style.color = ‘red‘;

After encapsulation

?
1234 functiona(selector, color) {document.querySelectorAll(selector)[].style.color = color}a(‘#a‘, ‘red‘);

From a dozens of-letter long line to a simple function call, the API is easy to use

2. Accessibility

A (' #a ', ' red ') is a good function that helps us to change an element in a simple and practical way, but the question is, if the person who first uses the modifier will be confused, what function a function is, and no one tells him. Development interface It is necessary to know that people are lazy, from the color assignment of this function, although less code, but increased the cost of memory. Each time you do this, you need to have a mapping relationship. A---->color. If it's a few simple, but usually a set of frameworks have dozens of or even hundreds of APIs, the increase in mapping costs will cause the programmer brother collapse. What we need is to make the interface meaningful, so let's rewrite the A function:

?
123 functionletSomeElementChangeColor(selector, color) {document.querySelectorAll(selector, color);}

Letsomeelementchangecolor is given a linguistic meaning relative to a, and anyone will know what it means.

3. Reduce memory costs

That's what we just did. It's too long, letsomeelementchangecolor. Although it reduces the cost of mapping, it increases the cost of memory. You know, everyone, including genius, doesn't like to be words. Native Get Dom API also has this problem document.getelementsbyclassname; document.getelementsbyname; Document.queryselectorall; These APIs give the impression that the word is too long, although the meaning he gives is clear, but it is based on the sacrifice of simplicity. So we rewrite the previous function again.

?
123 functionsetColor(selector, color) {xxxxxxxxxxxx}

Reduce the function name under the condition that the meaning is not large. Make it easy to read easy to remember easy to use;

4. Can be extended

Extension refers to the use of functions like flowing water in the order in which they are written to form the chain of execution:

?
123 document.getelementbyid ( ' id ' ' red ' ; document.getelementbyid ( ' ID ' ' px ' document.getelementbyid ( ' ID ' ' Pink '

Before using our previous method is to encapsulate again two function setfontsize, SetBackgroundColor; Then execute them setcolor (' id ', ' red '); Setfontsiez (' id ', ' 12px '); SetBackgroundColor (' id ', ' pink '); Obviously, this kind of practice does not have the lazy state, the ID element needs to regain each time, affects the performance, the failure, each time needs to add the new method fails each time to call these methods, or fails. Let's rewrite it as a function that can be extended to first encapsulate the Get ID method into an object, and then return the object in every method of the object:

?
123456789101112131415161718 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;}//调用var el = new getElement(‘#id‘)el.color(‘red‘).background(‘pink‘).fontSize(‘px‘);

Simple, fluid, easy to read, we'll talk about how to optimize in the parameters. So, everyone prefers to use jquery's API, although a $ symbol does not represent any practical significance, but simple symbols are beneficial to our use. It embodies the above principles, simple, easy to read, easy to remember, chain-style, multi-parameter processing.

Nightware:

?
123 document.getElementById(‘id‘).style.color = ‘red‘;document.getElementById(‘id‘).style.fontSize = ‘px‘;document.getElementById(‘id‘).style.backgourdColor = ‘pink‘;

Dream

?
1 $(‘id‘).css({color:‘red‘, fontSize:‘12px‘, backgroundColor:‘pink‘})

Second, consistency

1. Consistency of the interface

The relevant interface maintains a consistent style, and a full set of APIs that convey a sense of familiarity and comfort will greatly reduce the developer's adaptability to new tools. Name this: short, self-describing, and most importantly, consistency "in the computer science community there are only two headaches: cache invalidation and naming problems"-phil Karlton Choose a phrase you like and then use it consistently. Choose a style, and then keep that style.

Nightware:

SetColor,
Letbackground
Changefontsize
Makedisplay

Dream

SetColor;
SetBackground;
Setfontsize
Set .....

Try to keep the code style and naming style so that people read your code as if they were reading an article written by the same person.

Third, the processing of parameters

1. Types of parameters

Determine the type of parameter to provide a stable guarantee for your program

?
12345 //我们规定,color接受字符串类型functionsetColor(color) {if(typeofcolor !== ‘string‘) return;dosomething}

2. Using JSON to transmit parameters

There are many advantages of using JSON to pass a value, it can give the parameter name, can ignore the specific position of the parameter, can give the parameter default value and so on, such as the following bad situation:

function fn (param1, Param2...............paramn)

You have to follow each parameter in order, or your method will deviate from what you expect to do, and the correct approach is the following approach.

?
12345678 functionfn(json) {//为必须的参数设置默认值var default= extend({param: ‘default‘,param: ‘default‘......},json)}

This function code, even if you do not pass any parameters in, he will also be expected to run. Because at the time of declaration, you will decide the default value of the parameter according to the specific business.

Iv. Scalability

One of the most important principles of software design: Never modify an interface, refer to extend it! Scalability also requires an interface with a single, multi-duty interface that is difficult to scale. Give me a chestnut:

?
1234567891011121314151617181920 //需要同时改变某个元素的字体和背景 // Nightware:function set(selector, color) {document.querySelectroAll(selector).style.color = color;document.querySelectroAll(selector).style.backgroundColor = color;}//无法扩展改函数,如果需要再次改变字体的大小的话,只能修改此函数,在函数后面填加改变字体大小的代码//Dreamfunction set(selector, color) {var el = document.querySelectroAll(selector);el.style.color = color;el.style.backgroundColor = color;return el;}//需要设置字体、背景颜色和大小function setAgain (selector, color, px) {var el = set(selector, color)el.style.fontSize = px;return el;}

The above is simply add color, business complex and code is not when you write, you have to read the previous code and then modify it, obviously does not conform to the open-closed principle. The modified function returns the element object so that the return value is processed again the next time it needs to be changed.

Application of 2.this

Extensibility also includes the flexible use of this and the call and apply methods:

?
12345678 functionsayBonjour() {alert(this.a)}obj.a = ;obj.say = sayBonjour;obj.say();////orsayBonjour.call||apply(obj);//

V. Handling of Errors

1. Anticipating errors

You can use the type to detect typeof or Try...catch. typeof will force the detection object to not throw an error, especially useful for undefined variables.

2. Throwing errors

Most developers do not want to make mistakes and need to find their own code, the best way is to directly in the console output, tell the user what happened. We can use the output api:console.log/warn/error of the browser. You can also leave a few bridges to your program: Try...catch.

?
123456789101112 function error (a) { if ( typeof A!== ' string ' ) { Console.error ( ' param a must be type of string ' Code class= "JS plain" > } function error () { try { //Some code excucete here maybe throw wrong } catch (ex) { console.wran (ex); } }

VI. Predictability

The predictable Flavor program interface provides robustness to ensure that your code executes smoothly, and it must take into account abnormal expectations for it. Let's look at the difference between unforeseen code and predictable code with the previous SetColor

?
123456789101112131415161718192021222324252627282930313233343536373839404142434445 //nighwarefunction set(selector, color) {document.getElementById(selector).style.color = color;}//dreamzepto.init = function(selector, context) {var dom// If nothing given, return an empty Zepto collectionif (!selector) return zepto.Z()// Optimize for string selectorselse if (typeof selector == ‘string‘) {selector = selector.trim()// If it‘s a html fragment, create nodes from it// Note: In both Chrome and Firefox , DOM error // is thrown if the fragment doesn‘t begin with <if (selector[] == ‘<‘ && fragmentRE.test(selector))dom = zepto.fragment(selector, RegExp.$, context), selector = null// If there‘s a context, create a collection on that context first, and select// nodes from thereelse 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 readyelse if (isFunction(selector)) return $(document).ready(selector)// If a Zepto collection is given, just return itelse if (zepto.isZ(selector)) return selectorelse {// normalize array if an array of nodes is givenif (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 itelse if (fragmentRE.test(selector))dom = zepto.fragment(selector.trim(), RegExp.$, context), selector = null// If there‘s a context, create a collection on that context first, and select// nodes from thereelse 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 foundreturn zepto.Z(dom, selector)}

The above is the source of the Zepto, you can see, the author in anticipating the parameters of the input has done a lot of processing. Predictability, in fact, provides a number of entrances to the program, and is nothing more than a logical judgment. Zepto uses a lot of right and wrong judgments, which leads to lengthy code and is not suitable for reading. In short, predictability really requires you to do more to write some parameters about the physical location. The external detection is changed to internal inspection. Yes, the use of people comfortable and happy with ease. God The most important thing is Haisen.

Vii. readability of annotations and documents

One of the best interfaces is that no documentation is required and we will use it, but often the interface is a bit more and the business is increased, and the interface will be a little laborious to use. So the interface documentation and annotations need to be written carefully. The notes follow the principle of concise, and for many years later, they also show the following:

?
123456789 //注释接口,为了演示PPT用functioncommentary() {//如果你定义一个没有字面意义的变量时,最好为它写上注释:a:没用的变量,可以删除var a;//在关键和有歧义的地方写上注释,犹如画龙点睛:路由到hash界面后将所有的数据清空结束函数returngo.Navigate(‘hash‘, function(){data.clear();});}

At last

We recommend the Markdown Grammar writing API documentation, and the GitHub document writing syntax. Simple, fast, code highlighting, words not much to say

In-depth analysis of JavaScript API design principles (reproduced)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.