每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,欢迎关注开源日报。交流QQ群:202790710;微博:https://weibo.com/openingsource;电报群 https://t.me/OpeningSourceOrg

2018年7月29日:开源日报第143期

今日推荐开源项目:《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:

2018年7月29日:开源日报第143期

It also coerces certain “falsy” values into equality:

2018年7月29日:开源日报第143期

While others do not:

2018年7月29日:开源日报第143期

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.

2018年7月29日:开源日报第143期

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’.

2018年7月29日:开源日报第143期

But what does NaN think about being “not a number?”

2018年7月29日:开源日报第143期

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.

2018年7月29日:开源日报第143期

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

2018年7月29日:开源日报第143期

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:

2018年7月29日:开源日报第143期

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

2018年7月29日:开源日报第143期

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

2018年7月29日:开源日报第143期

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.

2018年7月29日:开源日报第143期

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