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

Detailed process record of Vue2 initiating requests using Axios

Table of contents Preface Axios installation and ...

Tutorial on installing Ceph distributed storage with yum under Centos7

Table of contents Preface Configure yum source, e...

CentOS 7 configuration Tomcat9+MySQL solution

Configure Tomcat First install Tomcat Installing ...

Detailed explanation of galera-cluster deployment in cluster mode of MySQL

Table of contents 1: Introduction to galera-clust...

vue-cropper component realizes image cutting and uploading

This article shares the specific code of the vue-...

MySQL Index Detailed Explanation

Table of contents 1. Index Basics 1.1 Introductio...

Detailed explanation of vue simple notepad development

This article example shares the specific code of ...

Docker generates images through containers and submits DockerCommit in detail

Table of contents After creating a container loca...

Two ways to implement HTML page click download file

1. Use the <a> tag to complete <a href=&...

Summary of various methods for JS data type detection

Table of contents background What are the methods...

How to change the mysql password on the Xampp server (with pictures)

Today, I found out while working on PHP that if w...

Mysql database index interview questions (basic programmer skills)

Table of contents introduction Indexing principle...

What is Software 404 and 404 Error and what is the difference between them

First of all, what is 404 and soft 404? 404: Simpl...