Javascript 我能决定调用一个不存在的对象方法时会发生什么吗?
我有如下代码:Javascript 我能决定调用一个不存在的对象方法时会发生什么吗?,javascript,Javascript,我有如下代码: obj.foo(); // obj might, or might not have a `foo` method. 我想知道我是否可以覆盖在我的代码中调用obj.foo时发生的情况,例如: obj.foo = function(){ alert ("Hello"); }); obj.onCallNonExistentMethod = function(){ // I know this is imaginary syntax alert("World"); } obj
obj.foo(); // obj might, or might not have a `foo` method.
我想知道我是否可以覆盖在我的代码中调用obj.foo
时发生的情况,例如:
obj.foo = function(){ alert ("Hello"); });
obj.onCallNonExistentMethod = function(){ // I know this is imaginary syntax
alert("World");
}
obj.foo(); // alerts "Hello"
delete obj.foo;
obj.foo(); // alerts "World" , would TypeError without the method missing handler.
据我所知,在Ruby中,这将是method\u missing
或const\u missing
或类似的东西
我可以重写JavaScript中调用不存在的对象方法时发生的事情吗?如果可以,我该怎么做
我们的目标是验证我提供给用户的API,以便他们可以安全地使用API,并且我可以更清楚地警告他们错误。不幸的是,这在任何广泛支持的方式下都是不可能的。最接近的方法是对所有调用使用代理函数,也就是说,不要使用
foo.bar()
而是使用类似foo.invoke('bar')
。然而,这很难看,很可能接近你在第一部分“不感兴趣”中的意思
在松散类型的语言中,期望开发人员传递兼容的对象是很常见的,也就是说,在传递意外的对象时出错通常是可以的
然而,如果您足够幸运地使用支持ECMAScript和谐特性的JS引擎(显然IE不支持),您可以使用来实现这一点。基本上,您可以将对象包装在代理中,这样就可以捕获对象,例如迭代对象、检索属性,甚至创建属性。除了这两个链接之外,还值得一试。如果您使用的是严格定义的对象,您应该使用自定义对象而不是对象文字:
function Foo(bar, baz) {
this.bar = bar;
this.baz = baz;
}
Foo.prototype = {
fizz: function () {
alert(this.bar + ' ' + this.baz + '!');
}
};
//elsewhere
f = new Foo('Hello', 'World');
f.fizz();
然后,您可以使用instanceof
操作符来判断对象是否为Foo
实例:
function Buzz(foo) {
if (foo instanceof Foo) {
foo.fizz();
}
}
f = new Foo('Hello', 'World');
Buzz(f);
如果您只是想检查对象是否包含特定参数处的函数,可以使用以下方法:
function hasFunction(obj, param) {
return (typeof obj[param] === 'function');
}
o = {
foo: function () {}
}
hasFunction(o, 'foo'); //true
hasFunction(o, 'bar'); //false
这在今天并不是很有用(因为浏览器支持不稳定),但将允许您编写代码来拦截对对象的属性访问。换句话说,当你写作时:
obj.foo();
代理的陷阱可以返回它想要的(被调用的)任何内容,而不管原始对象上是否存在属性。两年前,Benjamin,你对行为类型的概念不是很了解,是吗 幸运的是,在写了这个问题之后,您很快就会意识到这一点,即使是在JavaScript中,这也解决了您在这里提到的确切问题,只是从来没有使用过它 所以,要回答你的问题:
- 是的,这是完全可能做到的
- 你可能不应该为你所提供的情况负责
检查拼写错误的工具根本不足以在JavaScript中传达行为,类型检查通常被认为是一种反模式——在JavaScript、Ruby和Python等语言中,您知道将获得的类型。您的问题标题具有误导性。我希望有人能做一些像
var undefined=代码>@ThiefMaster,这是完全合法的,因为这不是他想要的。除此之外,现代JavaScript引擎阻止您重新定义全局未定义的
。感谢您的回答,但我明确表示我希望避免构造函数模式。我想做的是保存“hasFunction”的额外样板文件。如果您可以保证参数是函数或不存在,您可以使用foo.bar&&foo.bar()
作为简写,这在功能上与if(foo.bar){foo.bar()}
相同。这太棒了!遗憾的是,正如您所说,浏览器支持非常不稳定:/
var realObject = { foo: function(){ alert("Bar"); }); // our fooable api
var api = new Proxy({}, {
get: function(target, name){
if(name in target){ // normal API call
return target[name];
}
// return whatever you want instead of the method:
return function(){ alert("Baz"); });
}
});
api.foo(); //alerts Bar
api.bar(); //alerts Baz
api.IWillNotBuyThisRecordItIsScratched(); // alerts Baz