A detailed discussion of evaluation strategies in JavaScript

A detailed discussion of evaluation strategies in JavaScript

I was recently studying the application of η-transformation in lambda calculus in JavaScript, and happened to see an interesting question on stackoverflow. Regarding JavaScript's evaluation strategy, is the parameter passing of functions in js by value or by reference? The answer is classic.

A chestnut to cover it

function changeStuff(a, b, c) {
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num); // 10
console.log(obj1.item); // changed
console.log(obj2.item); // unchanged

If the parameter passing of the function in js is passed by value, then changing the value of b.item inside the function changeStuff will not affect the value of the external obj1 object.

If the function parameters in JS are passed by introduction, then the changes made inside the function changeStuff will affect all variable definitions outside the function. num will become 100 and obj2.item will become changed. Obviously this is not the case.

So we cannot say that function parameter passing in JS is strictly by value or by introduction. In general, function parameters are passed by value. JS also uses a parameter passing strategy called shared passing. It depends on the type of the parameter.

If the parameter is of a primitive type, it is passed by value;

If the parameter is a reference type, it is passed as shared.

Parameter passing

All function parameters in ECMAScript are passed by value. That is, copying a value outside a function to a parameter inside the function is just like copying a value from one variable to another. The transfer of primitive type values ​​is the same as the copying of primitive type variables, while the transfer of reference type values ​​is the same as the copying of reference type variables. -- Advanced JavaScript Programming

The Red Book says that all function parameters are passed by value. Is this true? Let's analyze the example above:

Pass by value

The strategy for primitive types as parameters in JavaScript is to pass by value (call by value):

function foo(a) {
  a = a * 10;
}

var num = 10;

foo(num);

console.log(num); // 10 no change

Here we can see that changes in the internal parameters of the function do not affect the external variables. Passing by value is correct.

By Shared Delivery

The strategy for passing objects as parameters in JavaScript is call by sharing:

Modifying the properties of a parameter will affect external objects

Reassignment will not affect external objects

According to the above example, the property item of parameter b is modified inside the function, which will affect the object outside the function, so the property item of obj1 is also changed.

function bar(b) {
  b.item = "changed";
  console.log(b === obj1) // true
}

var obj1 = {item: "unchanged"};

bar(obj1);

console.log(obj1.item); // changed Modifying the properties of the parameters will affect the external object

From the print result of b === obj1 being true, we can see that modifying the attribute of the parameter inside the function does not affect the reference of the parameter. b and obj1 share an object address, so modifying the properties of the parameter will affect the external object.

Reassigning parameter c to a new object will not affect the external object.

function baz(c) {
  c = {item: "changed"};
  console.log(c === obj2) // false
}

var obj2 = {item: "unchanged"};

baz(obj2);

console.log(obj2.item); // unchanged Reassignment will not affect the external object

Reassign parameter c to a new object, then c is bound to a new object address, and c === obj2 prints false, indicating that they no longer share the same object address. They each have a separate object address. So reassignment will not affect the external object.

Summarize

It can be said that passing by sharing is a special case of passing by value, where a copy of the reference address is passed. So what the Little Red Book says is correct.

You can think of the parameters of an ECMAScript function as local variables. -- Advanced JavaScript Programming

Extension - Lazy Evaluation

We have learned earlier that all function parameters are passed by value. In JavaScript, parameters must be evaluated first and then passed into the function as actual parameters. But there is a special case in ES6.

The default value of the parameter is not passed by value, but the value of the default value expression is recalculated each time. That is, parameter default values ​​are lazily evaluated. -- "ECMAScript 6 Primer"

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

In the above code, the default value of parameter p is x + 1. At this time, each time the function foo is called, x + 1 will be recalculated instead of the default p equal to 100

The above is a detailed discussion of the evaluation strategy in JavaScript. For more information about JavaScript evaluation strategy, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • In-depth understanding of JavaScript series (19): Evaluation strategy (Evaluation strategy) detailed explanation
  • How to write a javascript meta-circular evaluator
  • An example of a method to implement JavaScript lazy evaluation
  • JS implements a calculator function example that can evaluate arithmetic expressions
  • Detailed explanation of expression evaluation problem in the application of stack in JavaScript data structure
  • JS closure and delayed evaluation usage examples
  • javascript operand evaluation order
  • JavaScript+HTML to implement student information management system
  • Detailed explanation of this pointing problem in JavaScript
  • Take you to a thorough understanding of the prototype object in JavaScript

<<:  Detailed explanation of Frp forced redirection to https configuration under Nginx

>>:  How to install and configure the decompressed version of MySQL database under Linux system

Recommend

Implementation of Docker packaging image and configuration modification

I have encountered many problems in learning Dock...

Detailed tutorial on installing Tomcat8.5 in Centos8.2 cloud server environment

Before installing Tomcat, install the JDK environ...

Quickly install MySQL5.7 compressed package on Windows

This article shares with you how to install the M...

HTML table tag tutorial (11): horizontal alignment attribute ALIGN

In the horizontal direction, you can set the alig...

Detailed explanation of the entry-level use of MySql stored procedure parameters

Use of stored procedure in parameters IN paramete...

Advantages of INSERT INTO SET in MySQL

Insert data into mysql database. Previously commo...

Detailed tutorial on installing MySQL database in Linux environment

1. Install the database 1) yum -y install mysql-s...

Solve the problem of HTML automatic formatting after saving in vscode

The version of vsCode has been updated in recent ...

Detailed process record of nginx installation and configuration

Table of contents 1 Introduction to nginx 1 What ...

Example of how to enable Brotli compression algorithm for Nginx

Brotli is a new data format that can provide a co...

Detailed explanation of Redis master-slave replication practice using Docker

Table of contents 1. Background 2. Operation step...

Detailed explanation of Linux inotify real-time backup implementation method

Real-time replication is the most important way t...

Detailed steps to install CentOS7 system on VMWare virtual machine

Pre-installation work: Make sure vmware workstati...

How to obtain and use time in Linux system

There are two types of Linux system time. (1) Cal...