admin管理员组文章数量:1323735
this had me surprised:
var parts = email.split('@');
if (parts < 2) {
reference: .mailcheck.js#L21-22
essentially, it looks like:
var a = [null, null, null]
a < 2 // false
var b = [null]
b < 2 // true
so it seems like it works but I want to know why, what coercion actually happens for it to do this? as the intent here was to bail if less than 2 parts e from the email string, i would have expected it to always pass due to the array defined being truthy - it ought to create an array with at least 1 member even on an empty string.
i would always prefer to use array.length
. is the above safe?
this had me surprised:
var parts = email.split('@');
if (parts < 2) {
reference: https://github./Kicksend/mailcheck/blob/master/src/jquery.mailcheck.js#L21-22
essentially, it looks like:
var a = [null, null, null]
a < 2 // false
var b = [null]
b < 2 // true
so it seems like it works but I want to know why, what coercion actually happens for it to do this? as the intent here was to bail if less than 2 parts e from the email string, i would have expected it to always pass due to the array defined being truthy - it ought to create an array with at least 1 member even on an empty string.
i would always prefer to use array.length
. is the above safe?
-
1
Well,
array.length
isn't always safe either considering that it doesn't always readjust when an element is deleted ;) – Jeffrey Sweeney Commented Mar 21, 2012 at 21:59 -
1
@JeffreySweeney -
.length
always represents the actual length of the array. If an element is removed with something like.splice()
or.pop()
, then.length
will immediately and reliably return the new length. If you merely set an array element to undefined, that array element still exists and all the other array elements stay in their same locations so the.length
value correctly does not change. Can you describe when you think.length
is not accurate. – jfriend00 Commented Mar 21, 2012 at 22:18 - thanks for the replies, sanity check done, issue filed, i am not going insane... – Dimitar Christoff Commented Mar 21, 2012 at 22:22
-
@jfriend00
deleting
elements at the end of the array will not adjust thelength
property (perhaps intentionally), and there has been browser discrepancies in the past (hexmen./blog/2006/12/push-and-pop). In addition, it is way too easy to change the property itself, and a fallacious framework or lazy programmer can cause a lot of confusion. – Jeffrey Sweeney Commented Mar 21, 2012 at 22:28 -
@JeffreySweeney - you make no sense. So, how do you even propose to use an array if you don't use the
.length
property? And, what do you remend the OP do to solve their question. – jfriend00 Commented Mar 21, 2012 at 22:31
5 Answers
Reset to default 4It's a string and then number conversion that's happening, since arrays can't be directy pared with the <
operator. First it will do a string parison but with the number it will then do a number parsion.
Note that:
[null, null, null] == ",,"
[null] == ""
And:
+",,"
isNaN
+"" === 0
Now it makes sense because 0 < 2 === true
but NaN < 2 === false
.
It's therefore not a meaningful expression indeed. [null, null] < 3
is false
because "," < 3
is essentially doing NaN < 3
.
I get the feeling that it's not safe, because:
[0, 0] > 1 // false
and
[0, 0] < Infinity // false
Okay, it's not paring the number of elements at all. It pares the string representation of the array, hence NaN < Infinity
giving false
. So the answer is no, it's not at all a safe alternative because they don't do remotely the same thing. It only works for you because:
[null] < 2 -> null < 2 -> 0 < 2 -> true
but
[null, null, null] < 2 -> ',,' < 2 -> NaN < 2 -> false
Using the <
or >
operators to pare an array to a number is not safe, reliable or correct. You should not do it.
Here are the conversion rules taken from this O'Reilly book:
The operands of these parison operators may be of any type. Comparison can be performed only on numbers and strings, however, so operands that are not numbers or strings are converted. Comparison and conversion occur as follows:
If both operands are numbers, or if both convert to numbers, they are pared numerically.
If both operands are strings or convert to strings, they are pared as strings.
If one operand is or converts to a string and one is or converts to a number, the operator attempts to convert the string to a number and perform a numerical parison. If the string does not represent a number, it converts to NaN, and the parison is false. (In JavaScript 1.1, the string-to-number conversion causes an error instead of yielding NaN.)
If an object can be converted to either a number or a string, JavaScript performs the numerical conversion. This means, for example, that Date objects are pared numerically, and it is meaningful to pare two dates to see whether one is earlier than the other.
If the operands of the parison operators cannot both be successfully converted to numbers or to strings, these operators always return false.
If either operand is or converts to NaN, the parison operator always yields false.
In this particular case, since there is no conversion of an array to a number, it ends up paring two strings which is pletely unreliable.
This is yet another reason why you should only pare two items of the same type. In this particular case, it's also much, much more readable code to use the .length
property directly and use:
a.length > 2
Arrays cannot be converted to numbers. What's happening here is the arrays are being converted to strings.
When arrays are converted to strings, internally JavaScript does array.join(',')
.
So, ['a','b']
bees "a,b"
.
[null]
is ""
and [null,null]
is ","
. This is because null
is converted to a blank string.
So, [null,null] < 2
is "," < 2
which is false.
To get an array's length, use .length
.
Oh, its safe, it's just not paring what you think its paring.
The expression parts < 2
is paring an array to a number. To plete this parison, JavaScript must convert these two values to a mon type, and the only one available is string. The toString() method of the array object concatenates each of the string values of the arrays elements w/ a ma, and the string value of null is an empty string. So your test expressions are performing ",," < "2"
and "" < "2"
, which I'm certain isn't what's intended.
As long as you don't use delete
on the array (use slice
, instead), using length should be perfectly safe.
本文标签: javascriptweird arraylength alternative syntaxStack Overflow
版权声明:本文标题:javascript - weird array.length alternative syntax - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742118925a2421601.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论