Note: If there is any inappropriateness in the translation, please correct me. I wish you all a happy Double Holidays!
It is not good to extend native objects and prototypes without special needs
//Don’t do this
Array.prototype.map = function() {
// Some code
};
Unless it's worthwhile to do so, e.g. add some ECMAScript5 methods to some older browsers.
In this case, we generally do this:
if (!Array.prototype.map) {
Array.prototype.map = function() {
//Some code
};
}
If we are more paranoid, in order to prevent others from defining map as other unexpected values, such as true or others, we can change the detection code to the following:
if (typeof Array.prototype.map !== "function") {
Array.prototype.map = function() {
// Some code
};
}
(Although this will break other developers’ map definitions and affect the implementation of their functions)
However, in In a hostile and competitive environment (in other words, when you provide or use a js library), you should not trust anyone. What should you do if someone else's js code is loaded before yours and somehow defines a map() method that is not fully compatible with ES5, causing your code to not run properly?
However, you can trust the browser. If the Webkit kernel implements the map() method, you can rest assured that this method will definitely run normally. Otherwise, you have to use your code to detect it.
Fortunately, this is easy to implement in JavaScript. When you call the toString method of a native function, a string of a function will be returned. The function body of the function is [native code].
For example, under the Chrome console:
> ; Array.prototype.map.toString();
"function map() { [native code] }"
A proper code inspection is always a slightly unpleasant thing, Because different browsers treat spaces and line breaks too lightly. The test is as follows:
Array.prototype.map.toString() .replace(/s/g, '*');
// "*function*map()*{*****[native*code]*}*" // IE
// " function*map()*{*****[native*code]*}" // FF
// "function*map()*{*[native*code]*}" // Chrome
Simply removing the s will result in a more practical string:
Array.prototype.map.toString().replace(/s/g, '');
// "functionmap(){[nativecode]}"
You can encapsulate it into a reusable shim() function, so that you don’t have to repeat all the operations like!
Array.prototype... Such operations. This function will accept an object as a parameter (for example, Array.prototype), a property to be added (for example, 'map'), and a function to be added.
function shim(o, prop, fn) {
var nbody = "function" prop "(){[nativecode]}";
if (o.hasOwnProperty(prop) &&
o[prop].toString().replace(/s/g, ' ') === nbody) {
//The table name is native!
return true;
}
//Newly added
o[prop] = fn;
}
Test:
//This is the native method
shim(
Array.prototype, 'map',
function(){/*...*/}
); / / true
//This is the newly added method
shim(
Array.prototype, 'mapzer',
function(){alert(this)}
);
[ 1,2,3].mapzer(); // alerts 1,2,3
(End)^_^