search
HomeWeb Front-endJS Tutorial10 quirks and secrets about JavaScript_javascript tips

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:

Copy code The code is as follows:

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.

Copy code The code is as follows:

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:
Copy code The code is as follows:

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:

Copy code The code is as follows:

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:

Copy the code The code is as follows:

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:

Copy the code The code is as follows:

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 (==).

Copy code The code is as follows:

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:

Copy code The code is as follows:

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.
Copy code The code is as follows:

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().
Copy code The code is as follows:

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:

Copy code The code is 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 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.

Copy code The code is as follows:

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.
Copy code The code is as follows:

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:
Copy the code The code is as follows:

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:
7. The function can be executed In itself
The following is very OK:
Copy the code The code is as follows:

(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:
Copy code The code is as follows:

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.
Copy code The code is as follows:

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:
Browser
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:
Copy the code The code is as follows:


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:
Other miscellaneous
 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:
Copy the code The code is as follows:

var num1=0.1, num2=0.2, shouldEqual=0.3;
alert(num1 num2 == shouldEqual); //false

 And you can try this:
Copy code The code is as follows:

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:
Copy code The code is as follows:

var someVar;
alert(someVar = = undefined); //Show true

So far, everything seems calm and normal, but the plot is always bloody:
Copy code The code is as follows:

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.

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
揭示canvas属性的奥秘揭示canvas属性的奥秘Jan 17, 2024 am 10:08 AM

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

解密matplotlib颜色表:揭秘色彩背后的故事解密matplotlib颜色表:揭秘色彩背后的故事Jan 09, 2024 am 11:38 AM

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

揭秘真我手机品牌背后的秘密揭秘真我手机品牌背后的秘密Mar 24, 2024 am 08:57 AM

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

Linux稳如磐石的原因大揭秘:你所不知道的秘密Linux稳如磐石的原因大揭秘:你所不知道的秘密Mar 14, 2024 pm 02:33 PM

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

Golang图标背后的秘密:是狗吗?Golang图标背后的秘密:是狗吗?Mar 06, 2024 pm 05:54 PM

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

集成缓存:PHP高性能的秘密集成缓存:PHP高性能的秘密Jun 03, 2023 pm 09:31 PM

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

揭开CSS属性选择器的神秘面纱揭开CSS属性选择器的神秘面纱Jan 13, 2024 am 11:58 AM

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

淘宝的秘密武器:Go语言技术揭秘淘宝的秘密武器:Go语言技术揭秘Feb 26, 2024 pm 02:48 PM

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

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

MinGW - Minimalist GNU for Windows

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

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

MantisBT

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

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),