理解 Complex inArray 三元运算符
understanding Complex inArray ternary operator
我刚刚浏览了 inArray 方法代码并遇到了以下内容 ::
inArray: function (elem, arr, i) {
var len;
if (arr) {
if (indexOf) {
return indexOf.call(arr, elem, i);
}
len = arr.length;
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
for (; i < len; i++) {
// Skip accessing in sparse arrays
if (i in arr && arr[i] === elem) {
return i;
}
}
}
return -1;
},
现在我明白了三元运算符是如何工作的,但是有人能告诉我,下面这行代码是如何工作的吗?它甚至是三元运算符吗?
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
或者它是 JS 中的某种新结构?
谢谢。
Alex-z.
原声明:
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
为了更好地理解它,
i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0;
// ^ ^
是的,这是 嵌套 ternary operator
? :
。
以下是上述语句的if else
表示,逐步表示在if..else
中。
if (i) {
i = i < 0 ? Math.max(0, len + i) : i;
} else {
i = 0;
}
它的工作原理如下:
if (i) {
if (i < 0) {
i = Math.max(0, len + i);
} else {
i = i;
}
} else {
i = 0;
}
它是 2 个三元运算符,嵌套。你可以这样阅读:
i = i ? (i < 0 ? Math.max( 0, len + i ) : i) : 0;
或者,完全转换为if / else
:
if(i)
if (i < 0)
i = Math.max(0, len + i);
else
i = i;
else
i = 0;
您可以稍微缩短 if / else
结构:
if(i) {
if (i < 0)
i = Math.max(0, len + i);
} else
i = 0;
或:
if(i && i < 0)
i = Math.max(0, len + i);
if(!i)
i = 0;
这将删除多余的 else i = i
。在三元语句中,需要一个else
,但这里可以省略。
请记住,您在这些 if / else
语句中看到的所有 i =
赋值都是基于三元运算符前面的单个 i =
赋值。三元运算符本身 (a ? b : c
) 不会为变量赋值。
它以简单的逻辑分解为这个,当您编写代码时,您会想到什么。请注意,此函数不会捕获未定义的、nan 的空值、字符串、浮点数、布尔值、字节或任何可以被正常流程捕获的输入。
我认为这就是简化逻辑背后的意图。当我编写这样的代码时,这有点像我的想法。
function calculatewhat(i) {
if(i != 0) {/*i = i;*/ // i gets assigned and then evaluated.
//If its anything but zero it's true, if its zero its false.
if(i < 0) { // Test if its smaller than zero
return Math.max( 0, len + i ) ;
}
else { // its bigger than 0
return i
}
else { // if its 0... but you could just as wel return i
// instead of creating a new variable for the return since i is zero.
return 0;
}
}
我会编码而不是嵌套如下
i = i < 0 ? Math.max( 0, len + i ) : i
为了让 Cerbrus 满意,这就是它真正的工作原理。
function calculatewhat(i) {
if(i) { //check if its a true value. This will evaluate true also on "1", "blah",true, etc...
//To be typesafe you should make it an integer test. if(typeof i === 'number' && i !== 0);
if(i < 0) { // Test if its smaller than zero This will also return true on "-20" and -20.555
return Math.max( 0, len + i ) ;
}
else { // its bigger than 0 return i. but its type can be anything but an integer, so beware.
return i
}
else { //it's not a number or its 0.
//We can't be sure about type so lets return 0 to i making it a valid integer.
return 0;
}
}
两个三元组嵌套。
展开外层会得到:
var x;
if (i) {
x = i < 0 ? Math.max( 0, len + i ) : i;
} else {
x = 0;
}
i = x;
展开内部分支,然后得到:
var x;
if (i) {
if (i < 0) {
x = Math.max( 0, len + i );
} else {
x = i;
}
} else {
x = 0;
}
i = x;
x 表示重新分配给 i 的临时值。
Parens 可能会有所帮助(并且 parents 或换行符应该将它们分开,任何时候它们比 dirt-simple 更难):
i = i ? ( i < 0 ? Math.max( 0, len + i ) : i ) : 0;
现在你可以看到子表达式隐藏在外层三元的真正分支的中间。
实际上这就足够了:
if (i < 0) {
return Math.max(0, len + I);
}
正如其他答案中提到的,这是一个嵌套的三元组。我希望在这里提供的是该行为父函数执行的工作的自然语言翻译。
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
[------|----------------------|--] inner ternary
[--|----------------------------------|---] outer ternary
翻译:
i
? ...
: 0
(外三元)
如果从 i
开始搜索的索引作为参数提供给函数(这使用了如果未提供参数则 i
将是“假的”这一事实)然后继续评估内部三元并将 i
更新为结果,否则将 i
设置为 0.
i < 0
? Math.max(0, len + i)
: i
(内三元)
如果 i
小于零,return 数组长度 + i
(其中,由于 i
小于零,找到数组的索引元素 i
从数组末尾开始的位置),下限为零;否则 return i
.
我们现在可以看到,这一行允许函数将正整数解释为从数组开始的位置,将负整数解释为从数组末尾开始的位置,同时包括数组边界限制位置索引,还允许完全省略参数以默认为数组开始。
我刚刚浏览了 inArray 方法代码并遇到了以下内容 ::
inArray: function (elem, arr, i) {
var len;
if (arr) {
if (indexOf) {
return indexOf.call(arr, elem, i);
}
len = arr.length;
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
for (; i < len; i++) {
// Skip accessing in sparse arrays
if (i in arr && arr[i] === elem) {
return i;
}
}
}
return -1;
},
现在我明白了三元运算符是如何工作的,但是有人能告诉我,下面这行代码是如何工作的吗?它甚至是三元运算符吗?
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
或者它是 JS 中的某种新结构?
谢谢。
Alex-z.
原声明:
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
为了更好地理解它,
i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0;
// ^ ^
是的,这是 嵌套 ternary operator
? :
。
以下是上述语句的if else
表示,逐步表示在if..else
中。
if (i) {
i = i < 0 ? Math.max(0, len + i) : i;
} else {
i = 0;
}
它的工作原理如下:
if (i) {
if (i < 0) {
i = Math.max(0, len + i);
} else {
i = i;
}
} else {
i = 0;
}
它是 2 个三元运算符,嵌套。你可以这样阅读:
i = i ? (i < 0 ? Math.max( 0, len + i ) : i) : 0;
或者,完全转换为if / else
:
if(i)
if (i < 0)
i = Math.max(0, len + i);
else
i = i;
else
i = 0;
您可以稍微缩短 if / else
结构:
if(i) {
if (i < 0)
i = Math.max(0, len + i);
} else
i = 0;
或:
if(i && i < 0)
i = Math.max(0, len + i);
if(!i)
i = 0;
这将删除多余的 else i = i
。在三元语句中,需要一个else
,但这里可以省略。
请记住,您在这些 if / else
语句中看到的所有 i =
赋值都是基于三元运算符前面的单个 i =
赋值。三元运算符本身 (a ? b : c
) 不会为变量赋值。
它以简单的逻辑分解为这个,当您编写代码时,您会想到什么。请注意,此函数不会捕获未定义的、nan 的空值、字符串、浮点数、布尔值、字节或任何可以被正常流程捕获的输入。
我认为这就是简化逻辑背后的意图。当我编写这样的代码时,这有点像我的想法。
function calculatewhat(i) {
if(i != 0) {/*i = i;*/ // i gets assigned and then evaluated.
//If its anything but zero it's true, if its zero its false.
if(i < 0) { // Test if its smaller than zero
return Math.max( 0, len + i ) ;
}
else { // its bigger than 0
return i
}
else { // if its 0... but you could just as wel return i
// instead of creating a new variable for the return since i is zero.
return 0;
}
}
我会编码而不是嵌套如下
i = i < 0 ? Math.max( 0, len + i ) : i
为了让 Cerbrus 满意,这就是它真正的工作原理。
function calculatewhat(i) {
if(i) { //check if its a true value. This will evaluate true also on "1", "blah",true, etc...
//To be typesafe you should make it an integer test. if(typeof i === 'number' && i !== 0);
if(i < 0) { // Test if its smaller than zero This will also return true on "-20" and -20.555
return Math.max( 0, len + i ) ;
}
else { // its bigger than 0 return i. but its type can be anything but an integer, so beware.
return i
}
else { //it's not a number or its 0.
//We can't be sure about type so lets return 0 to i making it a valid integer.
return 0;
}
}
两个三元组嵌套。
展开外层会得到:
var x;
if (i) {
x = i < 0 ? Math.max( 0, len + i ) : i;
} else {
x = 0;
}
i = x;
展开内部分支,然后得到:
var x;
if (i) {
if (i < 0) {
x = Math.max( 0, len + i );
} else {
x = i;
}
} else {
x = 0;
}
i = x;
x 表示重新分配给 i 的临时值。
Parens 可能会有所帮助(并且 parents 或换行符应该将它们分开,任何时候它们比 dirt-simple 更难):
i = i ? ( i < 0 ? Math.max( 0, len + i ) : i ) : 0;
现在你可以看到子表达式隐藏在外层三元的真正分支的中间。
实际上这就足够了:
if (i < 0) {
return Math.max(0, len + I);
}
正如其他答案中提到的,这是一个嵌套的三元组。我希望在这里提供的是该行为父函数执行的工作的自然语言翻译。
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
[------|----------------------|--] inner ternary
[--|----------------------------------|---] outer ternary
翻译:
i
? ...
: 0
(外三元)
如果从 i
开始搜索的索引作为参数提供给函数(这使用了如果未提供参数则 i
将是“假的”这一事实)然后继续评估内部三元并将 i
更新为结果,否则将 i
设置为 0.
i < 0
? Math.max(0, len + i)
: i
(内三元)
如果 i
小于零,return 数组长度 + i
(其中,由于 i
小于零,找到数组的索引元素 i
从数组末尾开始的位置),下限为零;否则 return i
.
我们现在可以看到,这一行允许函数将正整数解释为从数组开始的位置,将负整数解释为从数组末尾开始的位置,同时包括数组边界限制位置索引,还允许完全省略参数以默认为数组开始。