图像你有一个名为window.whatever
的全局变量。如果要存储到其中的新值不满足某些条件,是否可以阻止任何人更改其类型和值?
例如,如果变量不以"https://"开头,我不希望更改变量。
在这种情况下,window.whatever = "Hello"
和window.whatever = 15
会抛出错误,但window.whatever = "https://example.com/"
工作正常。
也许Object.defineProperty
会修复它,但我不知道如何解决。
Object.defineProperty(window, 'whatever', {
writable: true, //here I want to add a sort of condition
});
我试过这个:
Object.defineProperty(window,'whatever',{
set:function(x){
if (x.startsWith('https://')) this.whatever= x}
})
但是当我这样做时window.whatever = "https://example.com"
它说:Uncaught RangeError: Maximum call stack size exceeded
,它仍然没有定义
更新:提供更好的解决方案。在上一个中,__globalVar
没有隐藏,您可以直接访问它(读/写(。这可能不是最好的主意,所以这里有一个更好的方法:
(function () {
let privateValue = "Hello";
Object.defineProperty(window, "whatever", {
get: function () {
console.log("in getter");
return privateValue;
},
set: function (val) {
console.log("in setter");
if (typeof val === "string" && val.startsWith("https://")) {
privateValue = val;
} else {
throw "Invalid whatever";
}
},
});
})();
console.log(window.whatever);
window.whatever = "https://stackoverflow.com";
console.log(window.whatever);
window.whatever = "lalala123";
console.log(window.whatever);
现在privateValue
实际上是私人的。
这样的东西对你有用吗?我认为它的行为就像你描述的那样。
let __globalVar = 'Hello';
Object.defineProperty(window, 'whatever', {
get() {
console.log('in getter');
return __globalVar;
},
set(val) {
// put your logic here
console.log('in setter');
if( val.startsWith("https://") ) {
__globalVar = val;
} else {
throw "Invalid whatever"
}
}
})
console.log(window.whatever);
window.whatever = "https://google.com";
console.log(window.whatever);
window.whatever = "lalala123";
console.log(window.whatever);