Object.freeze()vs const

Ser*_*rov 115 javascript ecmascript-6

Object.freeze()似乎是一种过渡性的便捷方法,可以const在ES6中使用.

是否有两种情况都在代码中占据一席之地,或者是否有一种使用不可变数据的首选方法?

我应该使用Object.freeze()直到我使用支持的所有浏览器const然后切换到使用const

Fel*_*ing 202

const并且Object.freeze是两个完全不同的东西.

const适用于绑定("变量").它创建一个不可变的绑定,即您不能为绑定分配新值.

Object.freeze适用于,更具体地说,是对象值.它使对象不可变,即您无法更改其属性.

  • `const` 不是新的 `var`,`let` 是新的 `var` (9认同)
  • 基本上,`const` 是新的`var`;它只是块范围的并防止重新分配。您可以使用`let`,但实际上只有在您要更改变量指向的值时才需要使用,这对于循环控制/迭代器变量和简单类型(如数字和字符串)有意义,但不适用于大多数用途对象(包括数组)。如果你想要一个内容不能改变的对象/数组,那么除了用 `const` 声明它,你还应该在它上面调用 `Object.freeze()`。 (5认同)
  • @MuhammadShoaib:你正在比较苹果和橙子。`Object.freeze` 不会阻止您为变量分配不同的值,这就是 `const` 的用途。当您使用对象时,您的示例将显示相同的“问题”: `var Age = {years: 33}; 对象.冻结(年龄); 年龄={岁数:34};// 没问题`. 此外,原始值已经是不可变的...... (4认同)
  • 看来 **Object.freeze** 只适用于对象,而 **不适用于值类型。例如 `var 年龄 = 33; 对象.冻结(年龄); 年龄=34;//没问题`年龄仍然可以毫无问题地更改。 (2认同)

paw*_*wel 73

在ES5 Object.freeze中不适用于原语,这些原语可能const比使用对象更常用.你可以在ES6中冻结原语,但是你也可以支持const.

另一方面,const用于声明对象不会"冻结"它们,你只是不能重新声明整个对象,但你可以自由地修改它的键.另一方面,您可以重新声明冻结的对象.

Object.freeze 也很浅,所以你需要递归地将它应用于嵌套对象来保护它们.

var ob1 = {
   foo : 1,
    bar : {
        value : 2   
    }
};
Object.freeze( ob1 );

const ob2 = {
   foo : 1,
    bar : {
        value : 2   
    }
}

ob1.foo = 4;  // (frozen) ob1.foo not modified
ob2.foo = 4;  // (const) ob2.foo modified

ob1.bar.value = 4;  // (frozen) modified, because ob1.bar is nested
ob2.bar.value = 4;  // (const) modified

ob1.bar = 4;  // (frozen) not modified, bar is a key of obj1
ob2.bar = 4;  // (const) modified

ob1 = {};  // (frozen) ob1 redeclared
ob2 = {}; // (const) ob2 not redeclared
Run Code Online (Sandbox Code Playgroud)


İlk*_*kut 12

var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields
Run Code Online (Sandbox Code Playgroud)

上面的例子它完全使你的对象不可变.

让我们看下面的例子.

const obj = {
  a: 1,
  b: 2
};
obj.a = 13; // You can change a field
obj.newField = 3; // You can assign new field.
Run Code Online (Sandbox Code Playgroud)

它不会给出任何错误.

但如果你这样尝试

const obj = {
      a: 1,
      b: 2
    };
obj = {
 t:4
};
Run Code Online (Sandbox Code Playgroud)

它将抛出一个错误,例如"obj是只读的".

另一个用例

const obj = {a:1};
var obj = 3;
Run Code Online (Sandbox Code Playgroud)

它会抛出 Duplicate declaration "obj"

另外根据mozilla docs const解释

const声明创建对值的只读引用.它并不意味着它拥有的值是不可变的,只是不能重新赋值变量标识符.

这个例子是根据babeljs ES6的特点创建的.


Wil*_*een 12

摘要:

constObject.freeze()提供完全不同的目的.

  • const用于声明一个必须立即进行分配并且不能重新分配的变量.声明的变量const是块作用域而不是像声明的变量那样的函数作用域var
  • Object.freeze()是一种接受对象并返回相同对象的方法.现在,该对象不能删除任何属性或添加任何新属性.

示例const:

示例1:无法重新分配 const

以下代码抛出错误,因为我们尝试重新分配使用const关键字声明的变量foo ,我们无法重新分配它.

示例2:分配给的数据结构const可以进行变异

const object = {
  prop1: 1,
  prop2: 2 
}

object.prop1 = 5;   // object is still mutable!
object.prop3 = 3;   // object is still mutable!

console.log(object);  // object is mutated
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我们使用const关键字声明一个变量并为其分配一个对象.虽然我们无法重新分配这个名为object的变量,但我们可以改变对象本身.如果我们更改现有属性或添加新属性,这将有效.禁用对我们需要的对象的任何更改Object.freeze().

示例Object.freeze():

示例1:无法改变冻结对象

object1 = {
  prop1: 1,
  prop2: 2
}

object2 = Object.freeze(object1);

console.log(object1 === object2); // both objects are refer to the same instance

object2.prop3 = 3; // no new property can be added, won't work

delete object2.prop1; // no property can be deleted, won't work

console.log(object2); // object unchanged
Run Code Online (Sandbox Code Playgroud)

在这个例子中,当我们调用Object.freeze()object1作为参数提供时,函数返回现在"冻结"的对象.如果我们使用===运算符将新对象的引用与旧对象进行比较,我们可以观察到它们引用相同的对象.此外,当我们尝试添加或删除任何属性时,我们可以看到这没有任何影响(将在严格模式下抛出错误).

示例2:带有引用的对象未完全冻结

const object = {
  prop1: 1,
  nestedObj: {
    nestedProp1: 1,
    nestedProp2: 2,
  } 
}


const frozen = Object.freeze(object);

frozen.prop1 = 5; // won't have any effect
frozen.nestedObj.nestedProp1 = 5; //will update because the nestedObject isn't frozen

console.log(frozen);
Run Code Online (Sandbox Code Playgroud)

此示例显示嵌套对象(以及其他引用数据结构)的属性仍然是可变的.因此Object.freeze(),当对象具有引用属性(例如Arrays,Objects)时,不会完全"冻结"该对象.


Him*_*rma 10

简单点吧。

它们是不同的。检查代码上的注释,这将解释每种情况。

Const- 它是块作用域变量,如let,其值不能重新分配,重新声明。

这意味着

{
 const val = 10;  // you can not access it outside this block, block scope variable

}

console.log(val); // undefined because it is block scope 

const constvalue = 1;
constvalue = 2; // will give error as we are re-assigning the value;
const obj = { a:1 , b:2};

obj.a = 3;
obj.c = 4;
console.log(obj); // obj = {a:3,b:2,c:4} we are not assigning the value of identifier we can 
                  // change the object properties, const applied only on value, not with properties
obj = {x:1};     // error you are re-assigning the value of constant obj 
obj.a = 2 ;     // you can add, delete element of object
Run Code Online (Sandbox Code Playgroud)

整个理解是 const 是块作用域,它的值不会重新分配。

Object.freeze: 对象根属性是不可更改的,我们也不能添加和删除更多的属性,但我们可以重新分配整个对象。

var x = Object.freeze({data:1,
    name:{
    firstname:"hero", lastname:"nolast"
    }
});

x.data = 12;  // the object properties can not be change but in const you can do
x.firstname ="adasd"; // you can not add new properties to object but in const you can do

x.name.firstname = "dashdjkha"; // The nested value are changeable 

//The thing you can do in Object.freeze but not in const

x = { a: 1};  // you can reassign the object when it is Object.freeze but const its not allowed
Run Code Online (Sandbox Code Playgroud)

// 两者相似的一件事是,嵌套对象是可变的

const obj1 = {nested :{a:10}};
var obj2 =  Object.freeze({nested :{a:10}});

obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;
Run Code Online (Sandbox Code Playgroud)

谢谢。