te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Precedence: Logical or vs. Ternary operator - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Precedence: Logical or vs. Ternary operator - Stack Overflow

programmeradmin3浏览0评论

Consider the following:
(EDIT: I've amended the function slightly to remove the use or braces with the ternary operator)

function someFunction(start,end,step){
  var start = start || 1,
      end = end || 100,
      boolEndBigger = (start < end);   // define Boolean here
      step = step || boolEndBigger ? 1:-1;
  console.log(step); 
}

someFunction()
// step isn't defined so expect (1<10) ? 1:-1  to evaluate to 1

someFunction(1,10)  
// again step isn't defined so expect to log 1 as before

The problem:

someFunction(1,10,2) 
//step IS defined, shortcut logical OR || should kick in, 
//step should return 2 BUT it returns 1

I'm aware that this is easily fixed by using braces:

function range(start,end,step){
  var start = start || 1,
      end = end || 100,
      step = step || ((start < end) ? 1:-1);
  console.log(step); 
}

The question: Why doesn't the || operator get short-cut in this case?

I'm aware that the Logical OR has the lowest precedence among binary logical conditional operators but thought that it has higher precedence than the conditional Ternary operator?

Am I misreading the MDN docs for Operator precedence?

Consider the following:
(EDIT: I've amended the function slightly to remove the use or braces with the ternary operator)

function someFunction(start,end,step){
  var start = start || 1,
      end = end || 100,
      boolEndBigger = (start < end);   // define Boolean here
      step = step || boolEndBigger ? 1:-1;
  console.log(step); 
}

someFunction()
// step isn't defined so expect (1<10) ? 1:-1  to evaluate to 1

someFunction(1,10)  
// again step isn't defined so expect to log 1 as before

The problem:

someFunction(1,10,2) 
//step IS defined, shortcut logical OR || should kick in, 
//step should return 2 BUT it returns 1

I'm aware that this is easily fixed by using braces:

function range(start,end,step){
  var start = start || 1,
      end = end || 100,
      step = step || ((start < end) ? 1:-1);
  console.log(step); 
}

The question: Why doesn't the || operator get short-cut in this case?

I'm aware that the Logical OR has the lowest precedence among binary logical conditional operators but thought that it has higher precedence than the conditional Ternary operator?

Am I misreading the MDN docs for Operator precedence?

Share Improve this question edited Feb 3, 2017 at 14:34 Pineda asked Feb 3, 2017 at 14:09 PinedaPineda 7,5933 gold badges33 silver badges47 bronze badges 9
  • 5 "higher precedence" means that your code is being evaluated as (step || (start < end)) ? 1 : -1 – Niet the Dark Absol Commented Feb 3, 2017 at 14:13
  • “Higher precedence” means || is evaluated first, i.e. step || (start < end) is evaluated first. – Sebastian Simon Commented Feb 3, 2017 at 14:14
  • @NiettheDarkAbsol: that would mean that the ternary has greater precedence, right? MDN docs say otherwise... – Pineda Commented Feb 3, 2017 at 14:15
  • @Xufox: if that was the case then the 3rd call would return 2. It doesn't... – Pineda Commented Feb 3, 2017 at 14:15
  • @Pineda No… step || (start < end) ? 1 : -1 evaluates to step ? 1 : -1 because || is evaluated first and step is truthy. Then, step ? 1 : -1 is evaluated to 1 because step is truthy. – Sebastian Simon Commented Feb 3, 2017 at 14:18
 |  Show 4 more ments

2 Answers 2

Reset to default 13

Yes, the || operator has higher precedence than the conditional ?: operator. This means that it is executed first. From the page you link:

Operator precedence determines the order in which operators are evaluated. Operators with higher precedence are evaluated first.

Let's have a look at all the operations here:

step = step || (start < end) ? 1:-1;

The operator with the highest precedence is the () grouping operation. Here it results in false:

step = step || false ? 1 : -1;

The next highest precedence is the logical OR operator. step is truthy, so it results in step.

step = step ? 1 : -1;

Now we do the ternary operation, which is the only one left. Again, step is truthy, so the first of the options is executed.

step = 1;

JavaScript is loosely typed which means that whenever an operator or statement is expecting a particular data-type, JavaScript will automatically convert the data to that type.

Let's see some scenarios how it converts to other type

example 1.

if() statement expects a boolean value, therefore whatever you define in the brackets will be converted to a boolean.

JavaScript values are often referred to as being "truthy" or "falsey", according to what the result of such a conversion would be (i.e. true or false).

Remember if a value is truthy unless it’s known to be falsey.

Fortunately there are only six falsey -

  1. false (of course!)
  2. undefined
  3. null
  4. 0 (numeric zero)
  5. "" (empty string)
  6. NaN (Not A Number)

example 2.

var x = zoo || star ;

If zoo evaluates to true then the value of zoo is returned, otherwise the value of star is returned

example 3.

var str = '1' || '2';

'1' is not falsey so '1' will be returned result : str = '1';

example 4.

var str = '1' || (true) ? '2' : '3';

first of all precedence of ||(Logical OR) operator is greater than ?(Conditional) operator

so first ( '1' || (true) ) will be evaluated first

'1' is not falsey so '1' will be returned

Intermediate result : str = '1' ?' 2' : '3'

'1' is not truthy so '2' will be returned

Final result : str = '2'

example 5.

var str = '1' || (false) ? '2' : '3';

first of all precedence of ||(Logical OR) operator is greater than ?(Conditional) operator

so first ( '1' || (false) ) will be evaluated first

'1' is not falsey so '1' will be returned

Intermediate result : str = '1' ?' 2' : '3'

'1' is not truthy so '2' will be returned

Final result : str = '2'

Now it will be very easy to figure out in your scenario :)

发布评论

评论列表(0)

  1. 暂无评论