当我为内置对象的成员分配了错误的值时,Chromium(V8?)发出了警告:
这是我见过的最意外的有用和明确的警告。比较一下,例如,React中没有上下文或有意义的行号的不变违规警告。或者,我在验证函数中发生的console.warn
调用远离模块用户实际搞砸的地方。
有没有一种方法可以让我自己的一个类在为一个成员分配一个无效值时抛出一个错误/警告,它会显示在作业旁边,如图所示?
答案 0 :(得分:4)
是的,您可以使用访问者方法定义属性:
var obj = {
get foo() {
return this._foo;
},
set foo(value) {
if (/*...value is invalid...*/) {
throw new Error(/*...*/);
}
this._foo = value;
}
};
使用时,它们看起来就像普通属性一样:
obj.foo = "some value";
var x = obj.foo;
更多信息:specification | MDN
当然,有了上述内容,一个坚定的人可以改为分配给obj._foo
。如果您对此感到担心,可以在IIFE中定义访问者并使用局部变量作为支持值:
var obj = (function() {
var foo;
return {
get foo() {
return foo;
},
set foo(value) {
if (/*...value is invalid...*/) {
throw new Error(/*...*/);
}
foo = value;
}
};
})();
该访问器方法语法只是定义访问器的一种方法;您也可以通过Object.defineProperty
(spec | MDN)和Object.defineProperties
(spec | MDN)(或者同时)在现有对象上执行此操作通过指定第二个参数,使用Object.create
[spec | MDN]创建新对象。
defineProperty
示例:
var obj = {};
(function() {
var foo;
Object.defineProperty(obj, "foo", {
get: function() {
return foo;
},
set: function(value) {
if (/*...value is invalid...*/) {
throw new Error(/*...*/);
}
foo = value;
}
});
})();
在ES2015中,您也可以在使用class
时执行此操作;它看起来很像初始化语法,但在方法之间没有逗号:
class Thingy {
get foo() {
return this._foo;
}
set foo(value) {
if (/*...value is invalid...*/) {
throw new Error(/*...*/);
}
this._foo = value;
}
}
要避免obj._foo
问题,您可以使用WeakMap
(spec | MDN)来存储由this
键入的值:
let Thingy = (() => {
let foos = new WeakMap();
class Thingy {
get foo() {
return foos.get(this);
}
set foo(value) {
if (/*...value is invalid...*/) {
throw new Error(/*...*/);
}
foos.set(this, value);
}
}
})();
我已经使用了foo
特定的地图,但您也可以使用this
键入的地图将所有您的支持属性存储为对象