我正在尝试创建一个静态数组。但我发现它可以在运行时增加数组中的项。我如何在javascript中实现静态数组?为什么数组在javascript中是可变的?
var a = [];
//var a = new Array(3);
for (var i = 0; i < 5; i++) {
//a.push(i);
a[i] = i;
}
document.write(a);
答案 0 :(得分:9)
您可以使用Object.freeze
冻结数组:
"use strict";
var a = Object.freeze([0, 1, 2]);
console.log(a);
try {
a.push(3); // Error
} catch (e) {
console.error(e);
}
try {
a[0] = "zero"; // Error
} catch (e) {
console.error(e);
}
console.log(a);
不允许
有关详细信息,请参阅链接。如果只是希望保持大小不变但又想要更改条目值,请改用Object.seal
。
请注意,尝试更改现有属性是否会导致错误(与静默失败相反)取决于您是否处于严格模式。
ES5(2009年6月)中引入了{p>freeze
和seal
,因此应该存在于任何模糊的最新浏览器中。过时的浏览器不会有它们。
答案 1 :(得分:2)
使用最新的JS语法(旧浏览器需要填充):
var list = Object.seal([1,2,3])
Object.seal阻止对对象的进一步更改。
答案 2 :(得分:0)
听起来你想要一个immutable数组。
大多数语言都有不可变的集合,无论是内置还是来自库。 JS不会正常包含它们,但Facebook提供了一个包含所有典型的不可变集合类型的库。
虽然immutablejs没有这样的数组类型,但它确实有更传统的List
:
// skip index 0 if `minAge` is not 0
var startIndex = $scope.minAge !== 0 ? 1 : 0;
$scope.minAgeList = dataFact.dataDetails.minAgeData().slice(startIndex);
答案 3 :(得分:0)
您可以使用Object.defineProperties()
在属性描述符Object.preventExtensions()
设置writable:false
,configurable:false
,以防止将新属性添加到数组或对象中。
"use strict";
const ro = obj => {
const props = {};
const length = obj.length || Object.keys(obj).length;
const entries = Array.isArray(obj)
? [...obj, length].entries()
: Array.from(Object.keys(obj), prop => [prop, obj[prop]]);
for (let [key, value] of entries) {
props[key === length ? `length` : key] = {
value: value,
configurable: false,
writable: false
}
}
return Object.preventExtensions(Object.defineProperties(obj, props));
};
let arr = ro([1,2,3]);
try {
console.log(`arr[0]:${arr[0]}`);
console.log(`try to set arr[0] to ${arr[0] = 4}`);
} catch (e) {
console.error(e)
}
try {
console.log(`try to .push() to arr ${arr.push(4)}`);
} catch (e) {
console.error(e)
}
try {
console.log(`try to set .length of arr ${arr.length = 4}`);
console.log(arr.length);
} catch (e) {
console.error(e)
}
try {
console.log(`try to delete of arr[1] ${delete arr[1]}`);
console.log(arr.length);
} catch (e) {
console.error(e)
}
console.log(JSON.stringify(arr, null, 2));
let obj = ro({a:1, b:2, c:3});
try {
console.log(`obj["c"]:${obj["c"]}`);
console.log(`try to assign 4 to obj["c"]:${obj["c"] = 4}`);
} catch (e) {
console.error(e)
}
try {
console.log(`try to assign property "d" to obj:${obj["d"] = 4}`);
} catch (e) {
console.error(e)
}
try {
console.log(`try to delete property "b" of obj:${delete obj["b"]}`);
} catch (e) {
console.error(e)
}
console.log(JSON.stringify(obj, null, 2));