array.slice()使数据更私有吗?



如果返回arr,则arr可能发生突变。是否返回arr的副本允许更多的数据隐私?

原始代码


function foo() {
let arr = [];
function qux() {
return arr;
}
return {
qux,
}
}
let qux = foo().qux;
qux();

修改代码。这里qux返回arr.slice(),arr的副本,而不是原始数组的引用。

function foo() {
let arr = [];
function qux() {
return arr.slice();
}
return {
qux,
}
}
let qux = foo().qux;
qux();

Private"不应该用这个词。无论是否在返回之前对数组进行切片,函数的调用者仍然能够看到返回的内容。调用者还可以通过调用.toString来检查foo函数本身。如果你想要真正的隐私,函数实现隐藏是在第2阶段,有可能最终被集成到语言中,但现在还没有。

对于代码,切片确实使数据更加可控-这意味着,如果您计划稍后在foo中使用数组,您的模块不需要依赖于函数的调用者不改变数组。

也就是说,大多数人会说,在返回对象的任何地方返回对象的副本是相当过度的防御。更容易说的是,函数/库的消费者应该遵循的隐式标准,避免改变不属于您的对象除非明确允许。如果我正在使用一个库,并且我从库中返回了一个对象,并且我对它进行了修改,结果该对象(或与该对象相关的某些东西)停止了工作——这是我的责任,而不是库的责任。

通过"保密";我假设你的意思是对象中的数组不能从外部改变,例如必须保持不可变。为了在qux()方法中确保这一点,您可以进行深度复制。有几种方法可以使用对象对数组进行深度复制。最简单的(不一定是最快的)是一个JSON字符串化和解析:

function qux() {
return JSON.parse(JSON.stringify(arr));
}

注意,如果你的数组项都是一个简单的类型,如String, Boolean, Number,你可以使用arr.slice()而不是JSON.parse(JSON.stringify(arr))来保持原始数组的不可变。

最新更新