Home  >  Article  >  Web Front-end  >  Detailed analysis of JavaScript operator precedence (with examples)

Detailed analysis of JavaScript operator precedence (with examples)

不言
不言forward
2018-11-26 15:40:272079browse

This article brings you a detailed analysis of JavaScript operator precedence (with examples). It has certain reference value. Friends in need can refer to it. I hope it will be useful to you. Helps.

Having been writing JavaScript for two years, I thought I would not fall into the trap of syntax, but in fact I was slapped in the face. Recently, a handsome guy in the product development team asked me to discuss a problem. Question, in order to make it easier for everyone to read, I have abstracted the model of this problem:

var provider = {
    test: {
        $get: function(){
            return function anonymous(config){
            };
        }
    }
};
var type = "test";
var config = {};
new provider[type].$get()(config);

Why does this in function anonymous point to # when the above statement is run? ##window instead of the new object created by new. The first thing I thought when I heard this question was: Nani! How is it possible that this in the constructor corresponding to the new operator does not point to a newly created object instance? ? At that time, because I did not carefully abstract the problem from the business, I was actually a little confused. But when I thought about it carefully, what exactly did this sentence express?

Thinking

Before talking about the meaning of this expression, let me tell you a few little things about the new operator:

Return of constructor

The JavaScript constructor can return a value or not, for example:

function Person(){

}
var person = new Person()
We know that the constructor returns the created instance at this time Object, that is, the object pointed to by

this in the constructor. But when your constructor has a return value, you have to differentiate based on the situation. If a non-reference type value is returned, what is actually returned is still a newly created instance object. But when a value of a reference type is returned, the reference object itself is returned. For example:

function Person(){
    return function(){}
}
var person = new Person()
typeof person // "function"
In JavaScript, functions, as first-class citizens, are essentially reference types, so person is the returned anonymous function.

Two forms of new operator

In fact, in MDN’s new operator description, the syntax is

new constructor[([arguments])]

You will find ([arguments ]) surrounded by square brackets means that it can be omitted. Therefore, if there is no difference between new Person() and new Person for a constructor without parameters, then we will think about a question. For the previous As for the Person that returns the function, when new Person() is executed, why is new Person() executed instead of (new Person)()? If you have read one of my previous articles, you know that the new operator with parameters has a higher priority than the new operator without a parameter list. So the first one will always be executed instead of the second one.

Detailed analysis of JavaScript operator precedence (with examples)

After understanding the above steps, we are close to the essence of the problem. How does the JavaScript engine parse the expression

new provider[type].$get()(config);
Into:

(new provider[type].$get())(config);
or

new (provider[type].$get())(config);
For the first form, (new provider[type].$get()) returns the anonymous function, so in anonymous(config) Internal this points to window. In the second mode, provider[type].$get() returns the anonymous function, so when running new anonymous(config), the internal this pointer points to the newly created instance this.

Of course we can see from the question: why this points to window instead of the new object created by new. In fact, what the author wanted to express at the time was the second meaning, but in fact it was expressed in the first way. The way is running. Why? The reason is very simple. In the first execution method, the JavaScript engine first parses the new operator with a parameter list, while in the second method, the function call is executed first, and then the new operator is executed. Let’s compare the above priorities. As you can see from the level diagram, new with a parameter list has higher priority than function calls, so it must be run in the first way.

In fact, this article does not have much useful information, but there are still two insights from it. First, from the previous similar article, I emphasized to avoid using such vague expressions and use more a few words. All problems with brackets can be easily solved. For example, some students will write something like:

var str = "Hello" + true ? "World" : "JavaScript";
Then what is the content of str? Some people may think it is Hello World, and some people may think it is World. In essence, The result of the above operation is World,

Because the operator priority is higher than the conditional operator, adding parentheses at this time will make your code easier to read. Second, stay in awe of technology. The biggest fear is that you think you know it all, but in fact you know nothing.


##

The above is the detailed content of Detailed analysis of JavaScript operator precedence (with examples). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete