Original author: Andy Croxall
Original link: Ten Oddities And Secrets About JavaScript
Translation editor: Zhang Xinxu
Data types and definitions
1. Null is an object
Among the many types of JavaScript, there is the Null type, which has a unique value of null, that is, its literal, defined as A value that makes no sense at all. It behaves like an object, as shown in the following detection code:
alert (typeof null); //Pop up 'object'
as shown below:
Although the typeof value shows "object", null is not considered an object instance. You know, the values in JavaScript are object instances, each value is a Number object, and each object is an Object object. Because null has no value, it is obvious that null is not an instance of anything. Therefore, the value below equals false.
alert(null instanceof Object); // is false
Translator’s Note: null can also be understood as an object placeholder
2. NaN is a numerical value
The original meaning of NaN is to represent a certain The value is not a numerical value, but it is a numerical value and is not equal to itself. It is strange. Look at the following code:
alert(typeof NaN); //pop up 'Number'
alert(NaN === NaN); //is false
The results are as follows:


Actually NaN is not equal to anything. To confirm whether something is NaN, you can only use isNaN.
3. Arrays without keywords are equivalent to false (about Truthy and Falsy)
Here is another great quirk of JavaScript:
alert(new Array() == false); // is true
The result is as follows:

To understand what is going on here, you need to understand the concepts of truthy and falsy. They are a true/flase literal. In JavaScript, all non-Boolean values have a built-in boolean flag. When the value is required to have boolean behavior, this built-in Boolean value will appear, such as when you want to compare with a Boolean value.
Since apples cannot be compared with pears, when JavaScript requires a comparison between two different types of values, it will first weaken them into the same type. false, undefined, null, 0, "", NaN are all weakened to false. This coercion does not always exist, only when used as an expression. Look at the following simple example:
var someVar =0;
alert(someVar == false); //display true
The results are as follows:

In the above test, we tried to compare the value 0 with the boolean value false. Since the two data types are incompatible, JavaScript automatically forced conversion into unified and equivalent truthy and falsy, where 0 is equivalent to false (as mentioned above) mentioned).
You may have noticed that there are no empty arrays in some of the above values that are equivalent to false. Just because the empty array is a strange thing: it itself is actually truthy, but when the empty array is compared with the Boolean type, its behavior is falsy. Not sure? There are reasons for this. Let’s take an example to verify the strange behavior of empty arrays:
var someVar = []; //Empty array
alert(someVar == false); //The result is true
if (someVar) alert('hello'); //The alert statement is executed, so someVar is treated as true
The result is as shown in the screenshot below, with two boxes popping up in succession:


Translator’s Note: The reason for this difference is that, according to the author, the array has a built-in toString() method. For example, when alerting directly, a string will pop up in the form of join(“,”), and an empty array will naturally It is an empty string, so it is equivalent to false. For details, please refer to the author's other article, "Twisted logic: understanding truthy & falsy". But what I personally find strange is that when empty objects, empty functions, weak equals true or false, false is displayed. Why? Is it really because arrays are a weirdo and need special considerations?
To avoid comparison problems with casts, you can use strong equals (===) instead of weak equals (==).
var someVar = 0;
alert(someVar = = false); //The result true – 0 belongs to falsy
alert(someVar === false); //The result false – zero is a numerical value, not a Boolean value
The result is as screenshot below (win7 FF4):


If you want to delve deeper into some unique quirks such as type coercion in JavaScript, you can refer to the official relevant document specifications:
section 11.9.3 of the ECMA-262
Regular Expression Formula
4. replace() can accept callback function
This is one of the least known secrets of JavaScript, first introduced in v1.3. In most cases, the use of replace() is similar to the following:
alert('10 13 21 48 52'.replace(/d /g, '*')); //Replace all numbers with *
This is a simple replacement, one character String, an asterisk. But what if we want to have more control over when replacement occurs? We only want to replace values below 30, what should we do? At this point, it is beyond your reach to rely solely on regular expressions. We need to use the callback function to process each match.
alert('10 13 21 48 52'.replace( /d /g, function(match) {
return parseInt(match) }));
When each match is completed, JavaScript applies a callback function and passes the matching content to the match parameter. Then, depending on the filtering rules in the callback function, either an asterisk is returned, or the match itself is returned (no replacement occurs).
The screenshot below:

5. Regular expressions: not just match and replace
Many JavaScript engineers only deal with regular expressions through match and replace. But there are far more regular expression-related methods defined by JavaScript than these two.
It is worth mentioning that test() works similarly to match(), but the return value is different: test() returns a Boolean type, used to verify whether it matches, and the execution speed is higher than match().
alert(/w{3,}/.test( 'Hello')); //Pop up 'true'
The above line of code is used to verify whether the string has more than three ordinary characters. Obviously "hello" meets the requirements, so true pops up.
The results are as follows:

We should also pay attention to the RegExp object, which you can use to create dynamic regular expression objects, for example:
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 credit card.');
Here, we dynamically create a matching verification based on the parameter word. The function of this test code is to select the word car without distinguishing between large and small selections. At a quick glance, the only word in the test English sentence is car, so the performance here is only one word. is used to represent word boundaries.
The results are as follows:
Function and Scope
6. You can pretend to be a scope
Scope is used to determine what variables are available, independent JavaScript (such as JavaScript is not in a running function) in the window object Operating in the global scope, the window object can be accessed under any circumstances. However, local variables declared in a function can only be used within that function.
var animal ='dog';
function getAnimal (adjective) { alert(adjective '' this.animal); }
getAnimal('lovely'); //pop up 'lovely dog'
Here our variables and functions are declared in in global scope. Because this points to the current scope, which is window in this example. Therefore, this function looks for window.animal, which is 'dog'. So far, so good. However, in practice, we can make a function run in a different scope and ignore its own scope. We can use a built-in method called call() to achieve scope impersonation.
var animal ='dog';
function getAnimal (adjective) { alert(adjective '' this.animal); };
var myObj = {animal: 'camel'};
getAnimal.call(myObj, 'lovely'); //pop up 'lovely camel' '
The first parameter in the call() method can pretend to be this in the function. Therefore, this.animal here is actually myObj.animal, which is 'camel'. The subsequent parameters are passed to the function body as ordinary parameters.
Another related one is the apply() method, which works the same as call(). The difference is that the parameters passed to the function are represented in the form of an array instead of independent variables. Therefore, if the above test code is represented by apply(), it is:
getAnimal.apply(myObj, ['lovely']); //Function parameters are sent in the form of array
In the demo page, the result of clicking the first button is as follows:

The result of clicking the second and third buttons is as follows:

The following is very OK:
(function() { alert('hello'); })(); // Pop up 'hello'
The parsing here is simple enough: declare a function, and then execute it immediately because of () parsing . You may wonder why we do this (referring to the direct () call), which seems a bit contradictory: functions usually contain code that we want to execute later, rather than parsing and executing it now, otherwise , we don’t need to put the code in the function.
Another good use of self-executing functions (SEFs) is to use bound variable values in deferred code, such as event callbacks, timeouts and intervals. Execution(intervals). The following example:
var someVar ='hello';
setTimeout(function() { alert(someVar); }, 1000);
var someVar ='goodbye';
Newbies always ask in the forum why the timeout popup here is goodbye instead Not hello? The answer is that the callback function in timeout does not assign the value of the someVar variable until it is run. At that time, someVar had been rewritten by goodbye for a long time.
SEFs provide a solution to this problem. Instead of implicitly specifying the timeout callback as above, the someVar value is directly passed in as a parameter. The effect is significant, which means that we pass in and isolate the someVar value, protecting it from changing whether there is an earthquake, tsunami, or the girlfriend is roaring.
var someVar = 'hello';
setTimeout( (function(someVar) {
returnfunction() { alert(someVar); }
})(someVar), 1000);
var someVar ='goodbye';
Things have changed, and this time, the pop-up here is hello. This is the difference between function parameters and external variables.
For example, the popup after clicking the last button is as follows:

8. FireFox reads and returns colors in RGB format instead of Hex
Until now I have not really understood why Mozilla It will look like this. In order to have a clear understanding, look at the following example:
Hello, world!
< ;script>
var ie = navigator.appVersion.indexOf('MSIE') !=-1;
var p = document.getElementById('somePara');
alert(ie ? p.currentStyle. color : getComputedStyle(p, null).color);
The pop-up result of most browsers is ff9900, but the result of FireFox is rgb(255, 153, 0), in the form of RGB. Often, when dealing with colors, we need to spend a lot of code to convert RGB colors to Hex.
The following are the results of the above code in different browsers:


9. 0.1 0.2 !== 0.3
This weird problem does not only appear in JavaScript , which is a common problem in computer science and affects many languages. The title equation outputs 0.30000000000000004.
This is a problem called machine precision. When JavaScript tries to execute the (0.1 0.2) line of code, it converts the value into its preferred binary flavor. This is where the problem starts, 0.1 is not actually 0.1, but its binary form. Essentially, when you write these values down, they are bound to lose precision. You might just want a simple two decimal places, but what you get (according to Chris Pine's comment) is a binary floating point calculation. For example, if you want to translate a paragraph into simplified Chinese, but the result is traditional, there are still differences.
There are generally two ways to deal with problems related to this:
Convert it to an integer and then calculate it, and then convert it to the desired decimal content after the calculation is completed
Adjust your logic and set the permission The range is not the specified result.
For example, we should not look like this:
var num1=0.1, num2=0.2, shouldEqual=0.3;
alert(num1 num2 == shouldEqual); //false
And you can try this:
alert(num1 num2 > shouldEqual - 0.001&& num1 num2
10. Undefined can be defined
We end with a gentle and drizzly little quirk. As strange as it may sound, undefined is not a reserved word in JavaScript, although it has a special meaning and is the only way to determine whether a variable is undefined. Therefore:
var someVar;
alert(someVar = = undefined); //Show true
So far, everything seems calm and normal, but the plot is always bloody:
undefined ="I'm not undefined!";
var someVar;
alert(someVar == undefined ); // Display false!
This is why the outermost closure function in the jQuery source code has an undefined parameter that is not passed in. The purpose is to protect undefined from being taken advantage of by external bad actors. And enter.

探索canvas属性的秘密,需要具体代码示例Canvas是HTML5中一个非常强大的图形绘制工具,通过它我们可以轻松地在网页中绘制出复杂的图形、动态的效果以及游戏等。但是,为了使用它,我们必须熟悉Canvas的相关属性和方法,并掌握它们的使用方式。在本文中,我们将对Canvas的一些核心属性进行探讨,并提供具体的代码示例,以帮助读者更好地理解这些属性应如何使

matplotlib颜色表详解:揭秘色彩背后的秘密引言:作为Python中最常用的数据可视化工具之一,matplotlib拥有强大的绘图功能和丰富的颜色表。本文将介绍matplotlib中的颜色表,探寻色彩背后的秘密。我们将深入研究matplotlib中常用的颜色表,并给出具体代码示例。一、Matplotlib中的颜色表颜色的表示方式在matplotlib中

真我手机品牌作为一线手机品牌,一直备受消费者的瞩目和关注。然而,众所周知,每一个成功的品牌背后都有着一段不为人知的历程和故事。本文将揭秘真我手机品牌背后的秘密,从品牌的起源、发展历程以及市场策略等方面进行深入探讨。真我手机品牌源自中国移动通信设备公司OPPOElectronicsCorp.于2018年正式推出,秉承“真我悦生活”的品牌理念。真我品牌致力于

Linux系统作为一款开源的操作系统,一直以来以其稳定性和可靠性著称,被广泛应用于服务器、嵌入式设备等领域。那么,Linux系统究竟是如何保持稳如磐石的呢?这其中究竟隐藏了怎样的秘密?本文将揭秘Linux系统稳定性的原因,并通过具体的代码示例来揭示这些秘密。1.开放的源代码Linux系统作为一个开源项目,其源代码对公众开放,任何人都可以查看和修改

Golang图标背后的秘密:是狗吗?Golang,即Go语言,是一种由Google开发的开源编程语言。它具有高效的并发处理能力、简洁的语法以及快速的编译速度,因而受到了广泛的关注和使用。而Golang的官方标志也备受瞩目,它的设计简洁而富有层次感,让人不禁联想到一只神秘的动物,究竟这个标志背后隐藏着怎样的秘密呢?有人猜想这个标志其实是一只狗的图形,那么这个猜

PHP是一种非常流行的编程语言,具有易于学习、功能强大和高度灵活的特点。然而,在处理大量数据和高并发请求时,PHP的性能问题往往会成为限制应用程序性能的瓶颈。为了解决这个问题,开发人员通常使用缓存技术来提高PHP应用程序的性能和可伸缩性。缓存是一种在内存中保存数据的技术,通过这种技术,应用程序可以快速地获取已经计算好的结果,而无需再次计算。在PHP中,缓存技

CSS属性选择器的秘密揭示CSS属性选择器是一种非常有用和强大的工具,它允许我们通过元素的属性值来选择和样式化特定的元素。这些属性选择器可以根据元素的属性值、属性值的出现位置以及属性值的特定字符等条件进行匹配和选择。本文将通过具体的代码示例来揭示CSS属性选择器的秘密。首先,让我们来了解一些基本的CSS属性选择器。最常见的属性选择器是“[attribute]

淘宝是中国最大的在线购物平台,每天有数以亿计的用户在上面购买商品。而在支撑这样一个庞大的平台运转中,技术方面起到了至关重要的作用。近年来,随着Go语言在互联网领域的流行,有人开始猜测是否淘宝的成功与Go语言有关。本文将从技术角度出发,具体探讨Go语言在淘宝中的应用,以及其可能成为淘宝秘密武器的原因。首先,我们来分析一下淘宝在技术上所面临的挑战。作为一个巨大的


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),
