最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - operator precedence and associativity with Math.Floor(Math.Random()) - Stack Overflow

programmeradmin0浏览0评论

I understand how the code works, in terms of the results it gives. First, it gets a random number, and, second, using Math.floor() it rounds down the results of Math.Random. Therefore, it's moving from right to left through the code.

Math.floor(Math.Random * num);

In the JavaScript Reference at this url and shown in the image below

it says that, for dot and parentheses, the associativity is "left to right". However, based on the code I excerpted above, I'd say it was "right to left." Please explain

I understand how the code works, in terms of the results it gives. First, it gets a random number, and, second, using Math.floor() it rounds down the results of Math.Random. Therefore, it's moving from right to left through the code.

Math.floor(Math.Random * num);

In the JavaScript Reference at this url and shown in the image below

it says that, for dot and parentheses, the associativity is "left to right". However, based on the code I excerpted above, I'd say it was "right to left." Please explain

Share Improve this question asked Dec 12, 2012 at 22:37 BrainLikeADullPencilBrainLikeADullPencil 11.7k24 gold badges82 silver badges138 bronze badges 2
  • 2 associativity != execution order – Bergi Commented Dec 12, 2012 at 22:40
  • right to left would mean: Math.(floor(num)) with error "floor is undefined" – Luca Rainone Commented Dec 12, 2012 at 23:01
Add a ment  | 

2 Answers 2

Reset to default 3

The associativity of operators has nothing to with their execution order, but how they are parsed.

Associativity "Left to right" means that a.b.c === (a.b).c !== a.(b.c).

When you have a function invocation, of course the arguments are evaluated first (at least in non-lazy languages like JS) - this is also defined in the specification.

What happens here is:

  • Math.floor(Math.Random * num); is parsed into an AST, according to the rules of operator precedence and associativity:

-\ invocation
 +-\ function: member operator
 | +-- base: variable "Math"
 | +-- property: "floor"
 +-\ arguments list
   +-\ first: Multiplication
     +-\ left operand: member operator
     | +-- base: variable "Math"
     | +-- property: "Random"
     +-- right operand: variable "num"
  • When evaluated, it happens top-down. The invocation first evaluates its function, calling the member operator on Math and floor. As this evaluates to a vaild function, it proceeds evaluating the arguments. The multiplication will first fetch its left operand, getting undefined from the member operator on Math and Random; then it fetches the value of the variable num. This results in NaN, and now the floor-function will be called with that, returning NaN again.

A function cannot be called without its arguments being resolved. This not not a matter of operator precedence (but execution order). The reason why a function call is left-associative is to make e.g. the following call work properly:

foo.bar.baz()

With the operator being left-associative this is equal to

((foo.bar).baz)()

which is equal to the original code. If it was right-associative you'd get the following:

foo.(bar.(baz())

That would obviously do something totally different which would most likely not work at all.

By the way, the function call is on a different precedence level than the member operators. See MDN for a better reference about this topic than the one you linked in your question.

发布评论

评论列表(0)

  1. 暂无评论