已废弃
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
__noSuchMethod__ 属性曾经是指当调用某个对象里不存在的方法时即将被执行的函数,但是现在这个函数已经不可用。
在__noSuchMethod__ 属性被移除之后,ECMAScript 2015 (ES6) 规范转而采用 Proxy 对象, 可以实现下面的效果(以及更多)。
语法
obj.__noSuchMethod__ = fun
参数
-
fun - 函数形式如下:
-
function (id, args) { . . . }-
id - 调用的不存在的方法名
-
args - 传递给该方法的参数数组
-
描述
默认情况喜爱,试图调用对象上不存在的方法其结果是在TypeError上抛出异常,这种行为可以在
By default, an attempt to call a method that doesn't exist on an object results in a arguments object.
If this method cannot be called, either as if undefined by default, if deleted, or if manually set to a non-function, the JavaScript engine will revert to throwing TypeErrors.
Examples
Simple test of __noSuchMethod__
var o = {
__noSuchMethod__: function(id, args) {
console.log(id, '(' + args.join(', ') + ')');
}
};
o.foo(1, 2, 3);
o.bar(4, 5);
o.baz();
// Output
// foo (1, 2, 3)
// bar (4, 5)
// baz ()
Using __noSuchMethod__ to simulate multiple inheritance
An example of code that implements a primitive form of multiple inheritance is shown below.
// Doesn't work with multiple inheritance objects as parents
function noMethod(name, args) {
var parents = this.__parents_;
// Go through all parents
for (var i = 0; i < parents.length; i++) {
// If we find a function on the parent, we call it
if (typeof parents[i][name] == "function") {
return parents[i][name].apply(this, args);
}
}
// If we get here, the method hasn't been found
throw new TypeError;
}
// Used to add a parent for multiple inheritance
function addParent(obj, parent) {
// If the object isn't initialized, initialize it
if (!obj.__parents_) {
obj.__parents_ = [];
obj.__noSuchMethod__ = noMethod;
}
// Add the parent
obj.__parents_.push(parent);
}
An example of using this idea is shown below.
// Example base class 1
function NamedThing(name){
this.name=name;
}
NamedThing.prototype = {
getName: function() { return this.name; },
setName: function(newName) { this.name = newName; }
}
// Example base class 2
function AgedThing(age) {
this.age = age;
}
AgedThing.prototype = {
getAge: function() { return this.age; },
setAge: function(age) { this.age = age; }
}
// Child class. inherits from NamedThing and AgedThing
// as well as defining address
function Person(name, age, address){
addParent(this, NamedThing.prototype);
NamedThing.call(this, name);
addParent(this, AgedThing.prototype);
AgedThing.call(this, age);
this.address = address;
}
Person.prototype = {
getAddr: function() { return this.address; },
setAddr: function(addr) { this.address = addr; }
}
var bob = new Person("bob", 25, "New York");
console.log("getAge is " + (("getAge" in bob) ? "in" : "not in") + " bob");
// getAge is not in bob
console.log("bob's age is: " + bob.getAge());
// bob's age is: 25
console.log("getName is " + (("getName" in bob) ? "in" : "not in") + " bob");
// getName is not in bob
console.log("bob's name is: " + bob.getName());
// bob's name is: bob
console.log("getAddr is " + (("getAddr" in bob) ? "in" : "not in") + " bob");
// getAddr is in bob
console.log("bob's address is: " + bob.getAddr());
// bob's address is: New York
Specifications
Not part of any specifications. This feature has been removed, see bug 683218.
Browser compatibility
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | 未实现 | 未实现 [1] | 未实现 | 未实现 | 未实现 |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | 未实现 | 未实现 | 未实现 [1] | 未实现 | 未实现 | 未实现 |
[1] This feature was implemented until version 43.