JavaScript: Prevent Array.push()
JavaScript: Prevent Array.push()
我有一个密封对象,其中包含一个数组成员,我希望在其上防止直接压入。
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d; }
});
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // pushed = sadness
我怎样才能防止推?
更新:
谢谢所有的想法。我最终需要将JSON发送到服务器。看起来我可能需要为数组使用对象,然后找出一种方法来生成和返回所需的JSON,或者更改_something以使用.slice()。将播放和报告
你可以重写push方法:
var _d = [];
_d.__proto__.push = function() { return this.length; }
,当您需要在模块中使用它时,调用Array.prototype.push
:
_b.addD = function (newD) {
Array.prototype.push.call(_d, newD);
};
我还没有对此做任何性能测试,但这肯定有助于保护您的数组。
(function(undefined) {
var protectedArrays = [];
protectArray = function protectArray(arr) {
protectedArrays.push(arr);
return getPrivateUpdater(arr);
}
var isProtected = function(arr) {
return protectedArrays.indexOf(arr)>-1;
}
var getPrivateUpdater = function(arr) {
var ret = {};
Object.keys(funcBackups).forEach(function(funcName) {
ret[funcName] = funcBackups[funcName].bind(arr);
});
return ret;
}
var returnsNewArray = ['Array.prototype.splice'];
var returnsOriginalArray = ['Array.prototype.fill','Array.prototype.reverse','Array.prototype.copyWithin','Array.prototype.sort'];
var returnsLength = ['Array.prototype.push','Array.prototype.unshift'];
var returnsValue = ['Array.prototype.shift','Array.prototype.pop'];
var funcBackups = {};
overwriteFuncs(returnsNewArray, function() { return []; });
overwriteFuncs(returnsOriginalArray, function() { return this; });
overwriteFuncs(returnsLength, function() { return this.length; });
overwriteFuncs(returnsValue, function() { return undefined; });
function overwriteFuncs(funcs, ret) {
for(var i=0,c=funcs.length;i<c;i++)
{
var func = funcs[i];
var funcParts = func.split('.');
var obj = window;
for(var j=0,l=funcParts.length;j<l;j++)
{
(function() {
var part = funcParts[j];
if(j!=l-1) obj = obj[part];
else if(typeof obj[part] === "function")
{
var funcBk = obj[part];
funcBackups[funcBk.name] = funcBk;
obj[part] = renameFunction(funcBk.name, function() {
if(isProtected(this)) return ret.apply(this, arguments);
else return funcBk.apply(this,arguments);
});
}
})();
}
}
}
function renameFunction(name, fn) {
return (new Function("return function (call) { return function " + name +
" () { return call(this, arguments) }; };")())(Function.apply.bind(fn));
};
})();
你可以这样使用:
var myArr = [];
var myArrInterface = protectArray(myArr);
myArr.push(5); //Doesn't work, but returns length as expected
myArrInterface.push(5); //Works as normal
这样,你可以在内部保留一个没有全局的接口副本,以允许你的辅助函数像正常一样修改数组,但是任何使用.push
.splice
等的尝试都会失败,要么直接,要么使用.bind(myArr,arg)
方法。
它仍然不是完全不透水,但是一个很好的保护器。您可以使用Object.defineProperty
方法为前900个索引生成受保护的属性,但我不确定这样做的含义。也有方法Object.preventExtensions()
,但我不知道有一种方法来撤销这种效果,当你需要改变它自己
谢谢你,dandavis!
我使用了slice方法:
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d.slice(); } // UPDATED
});
_b.updateC = function (newValue) {
_c = newValue;
};
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // no more update = happiness
这允许我防止直接push调用强制执行一些逻辑。
相关文章:
- NodeJS API调用中Array中的Push和Pull元素
- Array.push导致程序出错
- 带array.push()的双方括号---JavaScript
- 检测未绑定的本机函数,如“Array.push”
- JavaScript:为什么 array.push() 附加两个对象而不是一个对象
- 有时 array.length 只在 .push() 之后工作(为什么?)
- Array.push() 和唯一项
- 重复对象中的Array.push(),不正确或无法理解
- JavaScript array[“index”].push() 不起作用
- array.push.apply to implment 'concat' with explain
- Array.push受到Array.unshift后调用的影响
- JavaScript array.push (object) with Angular ng-repeat 无法按预期运
- 使用 array.push 正确编码
- Javascript Array.push 方法问题
- express.JS .push cousing array to be undefined
- 如果不在数组中 -> array.push
- 常规推送和 Array.prototype.push.apply 有什么区别?
- 仅使用 Array.push 时数组中的单位化变量
- javascript array.push(array.prush(x))奇怪的结果
- Push Array in Array