I still vaguely remember learning the ins and outs and cheering for myself that I had mastered an experience.
I still vaguely remember the feeling of helplessness and painful determination after being tortured by the same problem countless times.
First of all, I must thank those people who have made similar mistakes over and over even though I have stressed this issue countless times.
Without the encouragement of their repeated mistakes, perhaps I wouldn’t have seriously considered a solution to this problem.
Secondly, I must thank the author and translator of "JavaScript Advanced Programming".
Here I got the inspiration to solve this problem, otherwise I would still have to emphasize what should be paid attention to when using parseInt.
At the same time, hopefully more than just a solution is left here.
Keep here your ideas and ideas for solving problems, as well as your experience of drawing inferences about other problems.
Question:
I don’t want to recall painful memories of problems that happened a long time ago.
The question this time is very simple. When comparing two months, because the month is extracted from the string, parseInt is used to convert it.
The result after parseInt("08") is 0
For the reason, please refer to the explanation of the parseInt function on pages 19 to 20 of "JavaScript Advanced Programming" below.
The parseInt() method also has base mode, which can convert binary, octal, hexadecimal or any other base string into an integer.
The base is specified by the second parameter of the parseInt() method, so to parse hexadecimal values, you need to call the parseInt() method as follows:
var iNum1 = parseInt("AF", 16); //Return 175
Of course , for binary, octal or even decimal (default mode), you can call the parseInt() method like this:
var iNum1 = parseInt("10", 2); //return 2
var iNum2 = parseInt("10", 8); //return 8
var iNum3 = parseInt("10", 10); //Return 10
If a decimal number contains leading 0s, it's better to use base 10 so you don't accidentally get an octal value. For example:
var iNum1 = parseInt("010"); //returns 8
var iNum2 = parseInt("010", 8); //returns 8
var iNum3 = parseInt(" 010", 10); //Return 10
In this code, both lines of code parse the character "010" into a number.
The first line of code treats this string as an octal value and parses it the same way as the second line of code (which declares base 8). The last line of code declares base 10, so iNum3 ends up equal to 10.
First try:
The previous solution was for everyone to abandon the parseInt function and replace everything with parseFloat.
But as a human being, “who can never forget”?
The best way is to retain the "shape" of parseInt and abolish the "god" of parseInt.
So I thought of the instructions on "Redefining existing methods" on pages 87-88 of "Advanced JavaScript Programming".
3.6.2 Redefining existing methods
Just like you can define new methods for existing classes, you can also redefine existing methods.
As mentioned in the previous chapter, a function name is just a pointer to a function, so it can easily be made to point to other functions. What happens if local methods such as toString() are modified?
Function.prototype.toString = function () {
return "Function code hidden";
}
The previous code is completely legal, and the running results are exactly as expected:
function sayHi ( ) {
alert("Hello!");
}
alert(sayHi.toString()); //Output "Function code hidden"
Maybe you still remember, in Chapter 2 The toString() method introduced in Function usually outputs the source code of the function.
Override this method to return another string (in this case, "Function code hidden " ).
But what happened to the original function pointed to by toString()? It will be reclaimed by the garbage collector because it is completely obsolete.
There is no way to restore the original function, so before overwriting the original method, it is safer to store its pointer for future use.
You might even call the original method in a new method under certain circumstances:
Function.prototype.originalToString = Function.prtotype.toString;
Function.prototype.toString = function () {
if(this.originalToString().length >100) {
return "Function too long to display."
} else {
return this.originalToString();
}
at In this code, the first line of code saves the reference to the current toString() method in the attribute originalTo-String. Then override the toString() method with a custom method.
The new method will check whether the length of the function source code is greater than 100.
If so, return an error message indicating that the function code is too long, otherwise call the originalToString() method and return the source code of the function.
According to this example, just write a line
Global.prototype.parseInt = Global.prototype.parseFloat;
Then the parseInt function really becomes nothing more than an appearance. What is done is the function of parseFloat activity.
However, at the same time, a fatal problem is also in front of us.
That is the Global object in JavaScript, just like God, just a concept.
For instructions, please refer to the description of "Built-in Objects" on page 70 of "Advanced JavaScript Programming" below.
The Global object is the most special object in ECMAScript because it actually does not exist at all.
If you try to write the following code, you will get the error:
var pointer = Global;
The error message shows that Global is not an object, but didn’t it just say that Global is an object?
That’s right. The main concept to understand here is that in ECMAScript, there are no independent functions, all functions must be methods of some object.
The functions introduced earlier in this book, such as isNaN(), isFinite(), parseInt(), parseFloat(), etc., all look like independent functions.
Actually, they are all methods of Global object.
So, go online and check how to get the Global object, or how to use Global.prototype to change the parseInt function.
As you can imagine, the result is that God is God, and even the famous "Sou Shen Network" Google cannot find it.
When I was about to give up, I really responded to the saying "death comes before life".It suddenly occurred to me that parseInt is like a global function and does not need to be called by any object at all.
Does that mean that we just need to change the above sentence to parseInt = parseFloat;?
Sure enough, God is everywhere! ! ! It works! ! !
In-depth research:
The problem is basically solved. The only thing you need to pay attention to is that when there is an error in JavaScript loading, the following statements will not be loaded and executed.
So this sentence must be executed in the first sentence. Now we are just building a JavaScript universal method library, which requires that every page in the future must import this library file.
So put this sentence in the first line of the JavaScript general method library, and you can sit back and relax from now on.
But when I was writing comments for this code, especially when enumerating how to apply it, I found a problem with the following code
alert(parseInt("010", 2)); //10
alert(parseInt ("010", 8)); //10
alert(parseInt("010", 10)); //10
The return value of each processing is 10, which means that binary can be processed. Octal and hexadecimal parseInt have since disappeared.
If the single-parameter parseInt caused a lot of trouble, we still hope to retain its special functions for the two-parameter parseInt that did not cause trouble.
So further improvements are needed.
Then it is necessary to judge and process based on the number of parameters passed when using the parseInt function.
If there is only one parameter, then call parseFloat to return the result.
If there are more than two parameters, then call parseInt to process the two parameters and return the result.
The arguments object is used to determine the number of parameters here. See the description of the arguments object on pages 53-54 of "JavaScript Advanced Programming".
In function code, using the special object arguments, developers can access them without explicitly naming the parameters.
For example, in the function sayHi(), the first parameter is message.
You can also access this value, which is the value of the first argument, with arguments[0] (the first argument is at position 0, the second argument is at position 1, and so on).
Thus, the function can be rewritten without explicitly naming the arguments:
function sayHi() {
if (arguments[0] == "bye") {
return;
}
alert(arguments[0]);
}
So we have the following code:
originalparseInt = parseInt;
parseInt = function (){
if(arguments.length == 1){
return parseFloat(arguments[0]);
} else {
return originalparseInt(arguments[0], arguments[1]);
}
In this code we ParseInt has been modified to perform different processing based on the number of parameters.
Retains the prototype of parseInt with a new variable originalparseInt.
In this way, even if we transform parseInt, we can still use the original functions of parseInt through the retained prototype variable originalparseInt.
Back to nature:
When I wrote the code, I thought everything was OK, but someone said that it completely obliterated the parseInt function's processing of binary and octal systems.
Think about it too. The treatment is too extreme, and I just want to completely replace the annoying parseInt function with parseFloat.
If we are actually using binary or octal number conversion, we have to use the new prototype variable originalparseInt of the parseInt function that we have struggled to retain.
Actually, our wish is very simple.
When there is only one parameter in the parseInt function, I want it to simply handle the decimal conversion, so as not to cause some headache bugs because of the leading 0.
When we use the second parameter and want it to handle binary or octal, I can still use the existing functions of parseInt.
So we have the following final code:
Considering the size of the js file, try to reduce the amount of code as much as possible. So originalparseInt was replaced by $parseInt.
In addition, the super long built-in object name arguments are directly replaced by the letter a. In this way, the amount of code saved by using the object 4 times is very considerable.
Apply one example to other cases:
The reconstruction of the parseInt function is completed.
In fact, based on the experience of this transformation, we can transform JavaScript methods that have similar annoying characteristics to parseInt.
For example, methods such as escape and unescape that have been deprecated by the W3C organization can be replaced with recommended methods
escape = encodeURI;
unescape = decodeURI;
Then based on Based on this experience, if you encounter similar problems in the future, you can consider using this method of shifting the universe to solve them.