理解Javascript不可变变量

Ant*_*dis 33 javascript

我试图理解Javascript不可变变量的含义.如果我能做到:

var x = "astring";
x = "str";
console.log(x); //logs str` , then why it is immutable?
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一答案(从CI的一点点知道)是var x是指向具有值"astring"的内存块的指针,在第二个语句之后它指向另一个具有值"str"的块.是这样的吗?

还有一个额外的问题:我对Javascript的值类型感到困惑.引擎盖下的所有变量都是对象吗?偶数和字符串?

Git*_*LAB 52

是不可变的; 变量不是; 他们持有对(原始)价值观的引用.

三个基本类型string,number和boolean具有相应的类型,其实例是对象:String,Number,Boolean.
它们有时被称为包装类型.

以下值是原始的:

  • 字符串:"你好"
  • 数字:6,3.14(JavaScript中的所有数字都是浮点数)
  • 布尔:真实,虚假
  • null:通常是明确分配的
  • undefined:通常是默认(自动分配)值

所有其他值都是对象,包括基元的包装器.

所以:

  • 默认情况下,对象是可变的
  • 对象具有唯一的身份,并通过引用进行比较
  • 变量保存对象的引用
  • 原始是不可改变的
  • 基元按价值进行比较,它们没有个人身份

您可能会发现JavaScript Primitives的秘密生活是一个很好的解释.

此外,在ES6中有一个新的const关键字,它创建一个只读的命名常量,它不能通过赋值改变值或在脚本运行时重新声明.

希望这可以帮助!

  • 因此,如果我理解正确,那么与 C 相比,在 JavaScript 中,如果您有一个引用的内存位置,例如 var x = 1; 具有内容 0000000000000001 那么**“不变性”** 意味着我们不能将内存涂层的内容更改为 0000000000000011。如果是这种情况,那么如果我写 var x=1; x=2;每次 JavaScript 都会为我提供一个新的内存位置并垃圾收集旧的无人值守位置? (2认同)

aMo*_*her 18

首先,在C"字符串是一个字符数组,最后elem ='\ 0'".它们是可变的.
如果你在C中声明并初始化一个字符串,如下所示:

char str[] = "Foo";
Run Code Online (Sandbox Code Playgroud)

你基本上做的是保留4个字节(可能是8位字节,如果它伤害你,不要介意这个).str这个词用作指向这个数组的第一个elem的指针.所以,如果你喜欢这样:

str[0] or *(str) = 'G'
Run Code Online (Sandbox Code Playgroud)

然后它将改变该地址的值而不是创建新数组.您可以通过打印出str的地址来验证它.在这两种情况下它都是一样的.

现在,在JavaScript的情况下,字符串是原始类型.字符串上的所有操作都是通过值而不是通过引用来完成的.所以,这样做会产生真实的.

var str1 = "foo";
var str2 = "foo";
str1 === str2; => true
Run Code Online (Sandbox Code Playgroud)

字符串的初始化要求缓冲区适合"foo"并将名称str1绑定到它.使它们不可变的原因是你不能改变那个缓冲区.所以,你不能这样做:

str1[0] = 'G'
Run Code Online (Sandbox Code Playgroud)

执行此命令不会在非严格模式下产生警告或错误,但不会更改str1.你可以通过验证

console.log(str1) => "foo"
Run Code Online (Sandbox Code Playgroud)

但如果你喜欢这样:

str1 = "goo"
Run Code Online (Sandbox Code Playgroud)

你实际在做的是你要求一个新的缓冲区以适应"goo"并将标识符str1绑定到它.包含"foo"的旧缓冲区没有变化.

那么,"foo"会发生什么?

Java Script有一个自动垃圾收集器.当它看到一些内存不再可以被任何标识符引用时......或者它认为该内存是免费的.

布鲁尔数也是如此.现在,关于包装器对象!每当您尝试访问字符串上的属性时,如下所示:

str1.length;
Run Code Online (Sandbox Code Playgroud)

JavaScript使用String类创建一个新对象并在string上调用方法.一旦函数调用返回,对象就会被销毁.以下代码进一步解释:

var str = "nature"; 
str.does = "nurtures"; //defining a new property; 
console.log(str.does) => undefined
Run Code Online (Sandbox Code Playgroud)

因为物体已被摧毁.试试这个!

var str = new String("Nature");
str.does = "nurtures";
console.log(str) =>  ??
Run Code Online (Sandbox Code Playgroud)

这个str真的是一个对象......

结论:在C中,在单个作用域中,变量名称用作指针.所以,int,float,string都是可变的.但是在Java Script中,基本类型变量名称用作值而不是引用

参考文献:C++ primer plus,Java Script The Definitive Guide,C作者:Stephen Kochan


CBa*_*ass 5

你是对的.字符串(和数字)在java脚本(以及许多其他语言)中是不可变的.变量是对它们的引用.当您"更改变量的值"时,您正在更改变量引用的字符串(或其他),而不是值本身.


web*_*que 5

我认为许多新程序员相信不变性意味着原始值不能通过重新分配来改变。

var str = "testing";
var str = "testing,testing";
console.log(str); // testing, testing
Run Code Online (Sandbox Code Playgroud)

var fruits = ["apple", "banana", "orange"];

fruits[0] = "mango";

console.log(fruits); //["mango", "banana", "orange"]
Run Code Online (Sandbox Code Playgroud)

与可变和不可变类型关联的值可以通过重新分配来更改,如上述字符串和数组示例所示。但是,这些数据类型具有关联的函数(方法),用于操作属于每种数据类型的值。这是可变性/不变性被看到的地方。由于数组是可变的,因此数组方法的任何操作都会直接影响数组。例如,

var fruits = ["mango","banana", "orange"];
fruits.pop(); 
console.log(fruits) //["mango", "banana"]


The array.pop() method deleted "orange" from the original fruits array.
But with strings for example,


var name = "Donald Trump";
name.replace("Donald", "President");
console.log(name)//Donald Trump

the original string remains intact!
Run Code Online (Sandbox Code Playgroud)

不变性不允许通过字符串方法对原始字符串进行任何更改。相反,如果方法操作被分配给一个变量,则该方法会生成一个新字符串,如下所示:

var name = "Donald Trump";
var newName = name.replace("Donald", "President");
console.log(newName);//President Trump
Run Code Online (Sandbox Code Playgroud)