每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,歡迎關注開源日報。交流QQ群:202790710;微博:https://weibo.com/openingsource;電報群 https://t.me/OpeningSourceOrg


今日推薦開源項目:《JS+CSS+移動應用= NativeScript》傳送門:GitHub鏈接

推薦理由:這個項目是一個用 JS 和 CSS 構建移動應用的框架,並且可以跨平台使用一套 JS 代碼提供給安卓和 iOS 兩個版本。它內部還集成了 Vue 和 Angular,如果之前用過它們,現在用這個框架會很好使的,在做安卓和 iOS 開發的朋友可以看一看。


今日推薦英文原文:《Javascript Equality》作者:Devin Pierce

原文鏈接:https://medium.com/@devinmpierce/javascript-equality-a30095ffe4c7

推薦理由:JavaScript 中的相等,== 和 === 究竟有什麼不同,這篇文章講了在 JS 中各種各樣的相等與不相等

Javascript Equality

Javascript is host to a number of strange and unpredictable equality rules, that can lead to unexpected, hard to track bugs if you』re not aware of them.

First, let』s differentiate the equality operators, == and === . The main distinction between these two operators is that while the ===, or 「strict equality」 operator only sees equality between values of the same data type, the== , or 「abstract equality」 operator attempts to 「coerce」 values into the same data type, as seen here:

It also coerces certain 「falsy」 values into equality:

While others do not:

In my opinion, the implementation of == seems a bit inconsistent and unintuitive, and it is perhaps best avoided in most cases. In addition to avoiding using it wrong based on incorrect assumptions, your code will be more clear and readable if you handle type conversions explicitly yourself. If someone sees Number(string) === number , it is clear that one side expects a string. Likewise, value === undefined || value === null specifies that the value is expected to be one of the two. Ultimately, the small degree of brevity allowed by == does not seem worth the loss of clarity that it introduces, at least not to me.

If you』re not familiar with all of Javascript』s interesting interpretations of 「falsiness,」 that』s up next.

In Javascript, the following values evaluate to false:

  • false The Boolean, false
  • undefined The default, unassigned value, or lack of value
  • null Represents the same concept as undefined, but will only occur when it is assigned purposefully
  • '' An empty string
  • 0 The number zero
  • NaN Not a Number, the result of certain impossible math operations

The inclusion of '』and 0have always struck me as odd. While asserting the lack of value, such as with undefined and null , is a pretty standard logical operation, assuming an empty string or a zero value to be exceptional seems very presumptuous on the part of Javascript』s creators. Suppose you have a condition asserting the presence of a number, as opposed to undefined or NaN, but it is possible for that number to have evaluated to zero at some point. The conditional will not work properly unless you are more explicit in the condition expression.

NaN is the value returned when math goes wrong. In Javascript, rather than throwing an error, you will get NaN if you try to do something like 1 * 『a' , Math.sqrt(-1) , or Number('a') (trying to convert a letter string into a number.)

NaN has a very odd equality quirk of it』s own. Despite it』s name, NaN itself is actually of the data type 『number』.

But what does NaN think about being 「not a number?」

A value ashamed of it』s own identity. Tragic. But seriously, if we need to assert that a value is NaN, and it refuses to tell us, then what are we supposed to do? Well, fortunately there』s a function designed specifically for this very purpose. It』s contained in the Number object.

The last, and most complicated equality rule I』m going to cover here is object equality. Consider this case:

Two identical objects, and yet they will not be considered equal. Why not? Let』s try testing the same idea, but this time with Ruby hashes:

Ruby will figure it out. What』s different about Javascript? To answer that question, first consider another example from Ruby:

Two brand new, blank Ruby objects, containing nothing but what they inherit from their class, are identical in every way but one:

Their object ids differentiate them. They may be identical in their content, but they are still two separate instances, representing two distinct entities.

Compared to Ruby, Javascript objects effectively do double duty, both as the language』s dictionary-style key:value data structure, but also as it』s implementation of object-orientation instances, which means it』s necessary for them to exist as distinct entities, even when they are identical in value. So when Javascript』s equality operators check two objects, they are actually checking if the two operands are references to the same object.

Still, asserting key-value-equality between two separate objects is useful and sometimes necessary. The standard Javascript library actually has no way of doing this. But key-value-equality functions are common in Javascript libraries, including test frameworks, where they are particularly needed. Node.js also has it』s own implementation.

You may also write your own key-value-equality function. One thing to be careful of though: suppose you write a function that simply asserts the equality of two objects』 keys and primitive values. This is known as 「shallow-equality.」 This assertion will once again fail if there are any nested objects that are not referentially equal, even if their content is identical. To truly assert that a nested object structure is fully equal, even if none of the object references are the same, you will need what is known as a 「deep-equality」 function. This will need to utilize a recursive approach to ensure total key-value-equality to an indeterminate level.


每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,歡迎關注開源日報。交流QQ群:202790710;微博:https://weibo.com/openingsource;電報群 https://t.me/OpeningSourceOrg