There are no data structures that are simpler and more flexible than JavaScript objects. As a weakly dynamic type language, JavaScript does not have any constraints on the properties of the object, which results in the use of the time is very cool, want to add what attributes directly added to the line, there is no class or template restrictions, want to read what properties directly "point" out on the line, write it is quite concise However, when this code is running ...
One of the most flexible problems with JavaScript is the absence of constraints. For example, an online shop system has two parts, part of the production order object, the other part of the order to show the object. Our front-end programmers will naturally be behind the show that part of the matter, such as to show on the page the price of the goods on the order, it would drop order.product.price.sum. However, write the order of which part of the code of the buddy son is not necessarily reliable, there is a gift in the order there is no price, prices field simply did not, the front or the tune Order.product.price.sum, the JS code execution to this even if the dead, behind what also can not come. Even more frightening is that many systems now introduce node, the front and back end of the separation of the boundary to move back a section, this time in node to increase the use of order.product.price.sum, the entire page will not come out.
Do you think this example is quite low? It is estimated that your company has already stipulated that the product of the order data will have price field, even if the big brother will send you a {}. In addition, people are using Java, strong static type language, a variety of properties have long been defined, how can I lose it? Again before the line to test so long, how can be online on this problem?
Now that JSON is a standard data structure across the network, even if your backend is written in Java, the front end calls this write back-end interface to get the JSON. But what does this json turn from? Do you expect to be an object of a certain class? Cruelly Back-end eldest brother may have found that Java is too rigid, in order to fit the flexible JSON, people early use map. Besides, even if the backend is honest with class, if your online shop system is very large, there are several stores different kinds of orders, these orders are probably not from the same class bar, the field is inevitably different, you can ensure that your development team document complete to you can grasp all the properties of the class?
Anyway, we do not have such a full document, even if sometimes a little document, the back-end brother will be well-meaning to tell me: The code is the right!
If you want to put this missing field before the bug all detected, I feel too difficult to QA brothers, the back end of the data is not their decision, discouragement on the line after a long time suddenly really give less what.
People are always not reliable, but also have to find a way out of the code.
The most straightforward approach is to tread carefully: determine if a parent node exists at every call to a risky attribute. It is prudent to estimate the extent to which the source of the data should be judged. For an example of the total price of a previous item, there is no product in an order, so the code can look like this:
var showPriceif(order.product.price) showPrice = order.product.price
The actual situation is often more complex, such as I now want to take the data is the order of a product manufacturer's contact information inside a number of the first, and I do not trust the backend interface, even the order has no products are not guaranteed, then ...
var temp, temp1, temp2, temp3, phone;if ((temp = order.product) != null) { if ((temp1 = temp.seller) != null) { if ((temp2 = temp1.contact) != null) { if ((temp3 = temp2.phone) != null) { phone = temp3[0]; } } }}
So clumsy! If JS is going to write like this, I'd rather go back and write java!.
And no ~~ヾ (ˉ? ̄?)
I use Coffeescript. In fact, we are doing the project is not built and coffee above, but I use coffee, how to use is another topic, anyway with coffee, this code is this:
phone = order.product?.seller?.contact?.phone?[0]
Unfortunately, I am a number of people with obsessive-compulsive disorder, whenever I see so many question marks will be associated with the compilation of the heap if, I am tired of the computer. Again this question mark is easy to omit, quietly less a question mark is difficult to find. Anyway, I'll just put a question mark in front of the attribute that I think might be missing.
In fact, to do all these judgments is simply to return to undefined once a property is missing from the call chain. JS itself does not provide this thing, its own encapsulation of a.
Object.prototype.getAttr = function(path){ attrLink = path.split(‘.‘); var ref = this[attrLink[0]]; for(var i=1; i < attrLink.length; i++){ if(ref) ref = ref[attrLink[i]]; else return undefined; } return ref;}
So the access attribute is like this:
order.getAttr(‘product.seller.contact.phone.0‘)
This will be safe. But I would rather have the interpreter with the red exception in the debugging to tell me who is not defined or is empty and don't want to be quiet Mimi to get an undefined value. The way is, the code above will output a log when ref is empty. The final question is that the GetAttr method is not a mandatory method to get a property, it is not like Java, as long as the property is private, you can only use getter. Don't make sure that the other small partners must use this method to take properties, even I myself may have written written on the point directly. In the end, this object.getattr approach I have never used in actual development.
Feel the front of the kind of cofee inside add question mark of the way is enough, if we all feel that this property must have the back end interface is not pass that also too that what. But the real situation is that everything is possible, this can not blame the back-end eldest brother, maybe this order data is sent from other systems or is very old wonderful data.
What's the fuss? My principle is to minimize the loss as much as possible, that is, to minimize the range of code that affects the exception. This depends on the try. Catch.
Where try to see the code situation, it is impossible to catch which try. But there are some rules.
Those unreliable data should not be written by ourselves, but from the external interface, the code used for this interface data must have a certain range, at least the situation is to put this paragraph to try. It's too rough. Looking at the characteristics of the data, a large number of external data is often iterative, such as displaying a list of orders, there must be a loop on the order list, so for the loop inside try, so at most an order can not be displayed. There are local data there is no unified processing places, such as I do the node project using the handlebars template, the template will use a lot of custom helper, these helpers are mostly used to data processing to display the results, such as the format of the price or something. Coincidentally, these helpers have a unified code entry:
helpers = _.extend( require(‘./helper1‘), require(‘./helper2‘), require(‘./helper3‘))// “_”是underscore或者lodash
In fact, the helpers in each file is integrated into a large object, and then:
module.exports = _.reduce(helpers, function(memo, f, k){ memo[k] = function(){ try { return f.apply(this, arguments) } catch (e) { console.error(‘handlebars helper error‘, e) return ‘‘ } } return memo}, {})
All helper functions are wrapped in a try...catch before export. This way, a bug with missing fields in a helper can cause a little bit of something to show up.
In fact, I put all the helper into a large object in the original intention is not for this, but because each helper file is registered again look too much, feel uncomfortable. Isn't there a well-known code maintenance principle that probably says "any duplicated code should be avoided"? That's a good thing to see.
It seems to be perfect, or else. Later a buddy son and wrote a helper, did not put in my these helpers inside, but in other documents separately registered to, the result of wonderful data really appeared, tragedy really not to be staged ...
Well, at the end of the artifice all sorts of different kinds of cards, but not according to the rules. In fact, the front and back of all comrades to the data format, and strictly enforced, I wrote this whole pile of nonsense.
The object of JavaScript--flexibility and danger