Original Author: Andy Croxall
Original link: Ten oddities and secrets about JavaScript
Translation Editor: Rok Zhang Xinsen Xu
Data types and Definitions
1. Null is an object
JavaScript has a null type in many types, it has a unique value of NULL, that is, its literal amount, defined as a value that has no meaning at all. It behaves like an object, the following detection code:
Copy Code code as follows:
Alert (typeof null); Eject ' object '
Screenshot below:
Although the typeof value is displayed as "object", NULL is not considered an object instance. You know, the values in JavaScript are object instances, each numeric value is a number object, and each object is a objects object. Because NULL is not a value, it is clear that null is not an instance of anything. Therefore, the value below is equal to false.
Copy Code code as follows:
Alert (null instanceof Object); to False
Translator's note: null is also understood as an object-occupying selector.
2. Nan is a numerical value
Nan is meant to mean that a value is not a number, but it itself is numeric and not equal to itself, it's strange to see the following code:
Copy Code code as follows:
Alert (typeof NaN); Eject ' number '
Alert (nan = = Nan); to False
The results are as follows screenshot:
In fact Nan is not equal to anything else. To make sure that something is Nan, you can only use isNaN.
3. Arrays with no keywords are equivalent to False (about Truthy and Falsy)
Here's another Acura quirk of javascript:
Copy Code code as follows:
Alert (new Array () = false); is True
The results are as follows screenshot:
To know what's going on here, you need to understand the concept of truthy and Falsy. They are a true/flase literal amount. In JavaScript, all non-Boolean values are built with a Boolean flag, and when this value is required to have a Boolean behavior, the built-in Boolean value appears, such as when you want to compare Boolean values.
Because Apple can't compare with pears, when JavaScript two different types of values require comparisons, it first weakens them to the same type. False, undefined, null, 0, "", and Nan all weaken to false. This type of coercion is not always present, only when used as an expression. Look at the following simple example:
Copy Code code as follows:
var somevar = 0;
Alert (Somevar = = false); Show True
The results are as follows screenshot:
In the above test, we tried to compare the value 0 with the Boolean value false, because the data type of the two is incompatible, JavaScript is automatically coerced into the uniform equivalent of Truthy and Falsy, where 0 is equivalent to False (as mentioned above).
As you may have noticed, there are no empty arrays in some of the values equal to false above. Just because an empty array is a strange embryo: it actually belongs to Truthy, but when the null array is compared with the Boolean type, its behavior is falsy. Puzzled? This is due to the reason. Let's give an example to verify the strange temper of an empty array:
Copy Code code as follows:
var somevar = []; Empty array
Alert (Somevar = = false); Result true
if (somevar) alert (' Hello '); Alert statement executes, so somevar as True
The result is a screenshot of the following, which pops up two boxes in a row:
Translator Note: The reason for this difference, according to the author, the array built-in ToString () method, such as direct alert, will be in the form of join (",") pop-up string, empty array nature is an empty string, so the equivalent of false. Refer to the author's other article, "Twisted logic:understanding truthy & Falsy". But my personal surprise is that empty objects, null functions, Weak equals True or false, all show false, why? Really because the array is a freak, need special consideration?
To avoid the problem of forced conversions in comparison, you can use strong equals (= = =) instead of weak equals (= =).
Copy Code code as follows:
var somevar = 0;
Alert (Somevar = = false); Results true–0 belonged to Falsy
Alert (Somevar = = false); The result False–zero is a numeric value, not a Boolean
Results The following screenshot (Win7 FF4):
If you want to delve into the specific quirks of type coercion in JavaScript, refer to the official documentation specification:
Section 11.9.3 of the ECMA-262
Regular expressions
4. Replace () can accept callback functions
This is one of the most obscure secrets of JavaScript, introduced for the first time in v1.3. In most cases, the use of replace () is similar to the following:
Copy Code code as follows:
Alert ('/\d+/g, ' * ')); Replace all numbers with *
This is a simple replacement, a string, an asterisk. But what if we want to have more control over what happens when we replace it? We only want to replace the values below 30, what should we do? At this point, if only the regular expression is not beyond the reach. We need to use the east wind of the callback function to process each match.
Copy Code code as follows:
Alert ('/\d+/g '. Replace, function (match) {
return parseint (Match) <30? ' * ': match;
}));
When each match is completed, JavaScript applies the callback function, passing the matching content to the match parameter. Then, depending on the filter rule inside the callback function, either return the asterisk or return the match itself (no substitution occurs).
Screenshot below:
5. Regular expressions: Not just match and replace
Many JavaScript engineers are only dealing with match and replace and regular expressions. But the regular expressions defined by JavaScript are much more than these two.
One of the things worth mentioning is Test (), which works like match (), but the return value is not the same: test () returns a Boolean to verify that the match is performed faster than match ().
Copy Code code as follows:
Alert (/\w{3,}/.test (' Hello ')); Eject ' true '
The above line of code is used to verify that the string has more than three normal characters, and it is clear that "hello" is a requirement, so the popup is true.
The results are as follows screenshot:
We should also pay attention to the RegExp object, which you can use to create dynamic regular expression objects, such as:
Copy Code code as follows:
function Findword (Word, String) {
var Instancesofword = String.match (New RegExp (' \\b ' +word+ ' \\b ', ' IG '));
alert (Instancesofword);
}
Findword (' car ', ' Carl went-to-buy-a car but had forgotten-his-card. ');
Here, we have dynamically created matching validation based on the parameters word. This test code does this by selecting the word car without distinguishing between sizes. The eyes sweep past, test English sentence only one word is car, so the performance here is only one word. \b is used to denote the boundary of a word.
The results are as follows screenshot:
Functions and scopes
6. You can impersonate the scope
Scope This thing is used to determine what variables are available, and independent JavaScript (such as JavaScript is not in the Run-time function) operates under the global scope of the Window object, and the Window object can be accessed under any circumstances. However, a local variable declared in a function can only be used in that function.
Copy Code code as follows:
var animal = ' dog ';
function Getanimal (adjective) {alert (adjective+ ' +this.animal);}
Getanimal (' lovely '); Pop ' lovely dog '
Here our variables and functions are declared in the global scope. Because this points to the current scope, in this case it is window. So the function looks for window.animal, which is ' dog '. So far, everything is fine. In practice, however, we can let the function run under different scopes and ignore its own scope. We can use a built-in method called Call () to implement the scope of impersonation.
Copy Code code as follows:
var animal = ' dog ';
function Getanimal (adjective) {alert (adjective+ ' +this.animal);};
var myobj = {animal: ' camel '};
Getanimal.call (myobj, ' lovely '); Pop ' lovely camel '
The first argument in the call () method can impersonate this in a function, so the this.animal here is actually myobj.animal, which is ' camel '. The following arguments are passed as normal arguments to the function body.
Another relevant is the Apply () method, which acts on call (), except that the arguments passed to the function are expressed in an array rather than as independent variables. So the above test code, if applied (), means:
Copy Code code as follows:
Getanimal.apply (myobj, [' Lovely ']); Function arguments are sent as an array
In the Demo page, click on the results of the first button as follows screenshot:
The results of clicking on the second and third buttons are as follows:
7. Functions can perform their own
The following is OK:
Copy Code code as follows:
(function () {alert (' Hello ');}) (); Pop ' Hello '
Parsing here is simple enough: Declare a function and execute it immediately because () parsing. You might wonder why you're doing this (referring to the direct butt () call), which seems a bit paradoxical: the function usually contains the code we want to execute later, not the immediate parsing, otherwise we don't need to put the code in the function.
Another good use of the other execution function itself (self-executing functions (Sefs) is to use the binding variable value in the delay code, such as the callback (callback) of the event, timeout Execution (timeouts), and interval execution (intervals). The following example:
Copy Code code as follows:
var somevar = ' Hello ';
settimeout (function () {alert (somevar);}, 1000);
var somevar = ' goodbye ';
Newbies in the forum always asked here timeout pop-up why is goodbye rather than hello? The answer is to assign the value of the Somevar variable until it is run by the callback function in the timeout. At that time, Somevar had been rewritten by goodbye for a long time.
Sefs provides a way to resolve this problem. Instead of specifying the timeout callback implicitly, the Somevar value is passed directly in as a parameter. The effect is significant, which means that we have passed in and isolated the Somevar value, protecting it from either the earthquake tsunami or the girlfriend's roar.
Copy Code code as follows:
var somevar = ' Hello ';
SetTimeout ((function (Somevar) {
Returnfunction () {alert (somevar);}
}) (Somevar), 1000);
var somevar = ' goodbye ';
The wind water flow, this time, the pop-up here is hello. This is the point difference between the function argument and the external variable, huh.
For example, the last button clicked after the pop-up is as follows:
Browser
8. Firefox read and return colors in RGB format rather than hex
Until now I don't really understand why Mozilla is like this. To have a clear understanding, see the following example:
Copy Code code as follows:
<!--
#somePara {color: #f90;}
-->
<p id= "Somepara" >hello, world!</p>
<script>
var ie = navigator.appVersion.indexOf (' msie ')!=-1;
var p = document.getElementById (' Somepara ');
Alert (ie. p.currentstyle.color:getcomputedstyle (p, null). color);
</script>
Most of the browser pop-up results are ff9900, and Firefox is the result of RGB (255, 153, 0), RGB form. Often, when dealing with colors, we need to spend a lot of code to convert the RGB color to hex.
The following are the results of the above code in different browsers:
Other Assorted
9.0.1 + 0.2!== 0.3
This bizarre problem is not just in JavaScript, it's a pervasive problem in computer science that affects a lot of languages. The result of the title equation output is 0.30000000000000004.
This is a problem called machine precision. When JavaScript tries to execute (0.1 + 0.2) of this line of code, it converts the values into their preferred binary flavors. This is the origin of the problem, 0.1 is not actually 0.1, but a binary form. Essentially, when you write down these values, they are doomed to lose precision. You may just want to get a simple two-bit decimal, but what you get (according to Chris Pine) is a binary floating-point computation. Like you want to translate a paragraph should be translated into Simplified Chinese, the results are traditional, which is different from the same.
There are two general approaches to dealing with this issue:
Converted to integers, computed, and converted to desired decimal content.
Adjust your logic and set the allowable range to not specify the result.
For example, we should not be following this:
Copy Code code as follows:
var num1=0.1, num2=0.2, shouldequal=0.3;
Alert (num1 + num2 = = shouldequal); False
And you can try this:
Copy Code code as follows:
Alert (NUM1 + num2 > shouldequal-0.001&& num1 + num2 < shouldequal +0.001); True
10. Undefined (undefined) can be defined (defined)
We ended up with a gentle little freak. It may sound a little strange, undefined is not a reserved word in JavaScript, though it has special meaning and is the only way to determine whether a variable is undefined. So:
Copy Code code as follows:
var Somevar;
Alert (Somevar = = undefined); Show True
So far, everything looks calm and normal, but the plot is always dog blood:
Copy Code code as follows:
undefined = "I ' m not undefined!";
var Somevar;
Alert (Somevar = = undefined); Show false!
This is why the most external closure function in the jquery source code has a undefined parameter that is not passed in, and is designed to protect undefined from external bad.