JS 使用const声明常量的本质

在我们使用const声明常量时,总认为值一旦声明就不可改变,其实是有误解的;

刚在看ES6标准文档时,仔细阅读了const的解析,恍然大悟的感觉,分享给大家。

本质

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。

下面是另一个例子。

const a = [];
a.push(‘Hello‘); // 可执行
a.length = 0;    // 可执行
a = [‘Dave‘];    // 报错

上面代码中,常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。

如果真的想将对象冻结,应该使用Object.freeze方法。

const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === ‘object‘ ) {
      constantize( obj[key] );
    }
  });
};

原文地址:https://www.cnblogs.com/minigrasshopper/p/9144223.html

时间: 2024-11-12 14:33:21

JS 使用const声明常量的本质的相关文章

ES6学习之const声明常量的学习

在ES中const关键字用来声明常量,与C#中的类似 const声明的一经定义不能修改 和let特性差不多, const a = 13; console.log(a); a = 5; //报错 const定义完常量后必须赋值,后面不允许再次赋值 const aa; const b; //报错 const定义完后,必须赋值,后面不允许赋值 b=5; alert(b): const c = 12; (function () { console.log(c); //死区 访问不到 const c =

var,let,const声明变量?

var 与 let 的区别? 1.var支持变量预检测,let不支持 console.log(a); // undefined 程序不会报错 var a = 1; console.log(b); //程序报错 b is not defined let b = 2; 2.let 不支持重复声明 var a = 1; var a = 10; console.log(a); // 10 let b = 2; let b = 200; console.log(b); //程序报错 Identifier

max() 会认为其参数是不会被改变的,我们应该将 t1和t2声明为 const (常量)

在创建完成抽象操作的函数时,如:拷贝,反转和排序,你必须定义多个版本以便能处理每一种数据类型.以 max() 函数为例,它返回两个参数中的较大者: double max(double first, double second); complex max(complex first, complex second); date max(date first, date second); //..该函数的其它版本 尽管这个函数针对不同的数据类型其实现都是一样的,但程序员必须为每一种数据类型定义一个单

循环中的let和const声明

一.循环中的let声明 每次循环的时候let声明都会创建一个新变量i,并将其初始化为i的当前值,所以循环内部创建的每个函数都能得到属于他们的i的副本. 最初的: for (var i = 0 ; i < 10 ; i++) { array.push(function(){    console.log(i) })  };    array.forEach(function(func){         func()    }) 优化后: var array=[];   for (var i =

const限定常量或者变量(初次赋值后),其值不允许被改变

CONST(C中的CONST) const是一个C语言(ANSI C)的关键字,它限定一个变量不允许被改变,产生静态作用.使用const在一定程度上可以提高程序的安全性和可靠性.另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助.另外CONST在其他编程语言中也有出现,如A++.PHP5.B#.net.HC08 C.C#. 中文名 C语言的关键字 外文名 const 所属领域 计算机 格    式 C++.PHP5 目录 1 定义 2 目的 3 主要作用 4 

JS中const、var和let区别

在JavaScript中有三种声明变量的方式:var.let.const. 1.const 声明创建一个只读的常量.这不意味着常量指向的值不可变,而是变量标识符的值只能赋值一次,必须初始化. const b = 2;//正确 // const b;//错误,必须初始化 console.log('函数外const定义b:' + b);//有输出值 // b = 5; // console.log('函数外修改const定义b:' + b);//无法输出 2.var 语句用于声明变量. var a;

DWZ错误的解决:0x800a13af - Microsoft JScript 运行时错误: 重新声明常量“document”

在写完Login后,需要跳转到Index中,就是DWZ的主界面,结果出现如下问题: 0x800a13af - Microsoft JScript 运行时错误: 重新声明常量“document” 费了很大劲,网上基本没有解释. 最后自己发现了问题所在,是以下这段代码在搞乱: <!--[if lte IE 9]> <script src="~/DWZ/js/speedup.js"></script> <script src="~/DWZ/

ES6基础之const声明

问题 今天在分析React教程时,观察到如下代码: class Board extends React.Component { constructor(props) { super(props); this.state = { squares: Array(9).fill(null), }; } handleClick(i) { const squares = this.state.squares.slice(); squares[i] = 'X'; this.setState({squares

JS中函数声明与函数表达式的不同

Js中的函数声明是指下面的形式: function functionName(){ } 这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如: var functionName = function(){ } 可能很多朋友在看到这两一种写法时会产生疑惑,这两种写法差不多,在应用中貌似也都是可行的,那他们有什么差别呢? 事实上,js的解析器对函数声明与函数表达式并不是一视同仁地对待的.对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析,而函数表达式,如同