Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Obsolete since Gecko 43 (Firefox 43 / Thunderbird 43 / SeaMonkey 2.40)
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 містить об'єкт Proxy, який допоможе досягти описаного нижче (і навіть більше).

Синтаксис

obj.__noSuchMethod__ = fun

Параметри

fun
Функція, що має вигляд
function (id, args) { . . . }
id
Ім'я неіснуючого методу, що був викликаний
args
Масив аргументів, переданих у метод

Опис

За замовчуванням спроба викликати метод, який не існує, на об'єкті призводить до викидання TypeError. Цю поведінку можна обійти, визначивши функцію у властивості об'єкта __noSuchMethod__. Функція приймає два аргумента, перший - це ім'я метода, що викликається, другий - це масив аргументів, які передаються під час виклику. Другий аргумент є справжнім масивом (тобто, він успадковується через ланцюг Array.prototype), а не подібним до масиву об'єктом arguments.

Якщо цей метод не можна викликати, чи тому що він дорівнює undefined, чи був видалений, чи йому вручну було присвоєне нефункціональне значення, рушій JavaScript повернеться до викидання TypeError.

Приклади

Проста перевірка __noSuchMethod__

var o = {
  __noSuchMethod__: function(id, args) { 
                      console.log(id, '(' + args.join(', ') + ')'); 
                    }
};

o.foo(1, 2, 3);
o.bar(4, 5);
o.baz();

// Виведе
// foo (1, 2, 3)
// bar (4, 5)
// baz ()

Використання __noSuchMethod__ для імітації множинного спадкування

Приклад коду, що реалізує примітивну форму множинного спадкування, наведений нижче.

// Не працює, якщо батьківські об'єкти є результатом множинного спадкування
function noMethod(name, args) {
  var parents = this.__parents_;

  // Пройти через усі батьківські об'єкти
  for (var i = 0; i < parents.length; i++) {
    // Якщо знаходимо функцію у батьківського об'єкта, викликаємо її
    if (typeof parents[i][name] == 'function') {
      return parents[i][name].apply(this, args);
    }
  }

  // Якщо ми дістались сюди, метод не був знайдений
  throw new TypeError;
}

// Додавало батьківський об'єкт для множинного спадкування
function addParent(obj, parent) {
  // Якщо об'єкт неініціалізований, ініціалізуємо його
  if (!obj.__parents_) {
    obj.__parents_ = [];
    obj.__noSuchMethod__ = noMethod;
  }

  // Додати батьківський об'єкт
  obj.__parents_.push(parent);
}

Приклад використання цієї ідеї наведений нижче.

// Базовий клас 1
function NamedThing(name) {
  this.name = name;
}

NamedThing.prototype = {
  getName: function() { return this.name; },
  setName: function(newName) { this.name = newName; }
}

// Базовий клас 2
function AgedThing(age) {
  this.age = age;
}

AgedThing.prototype = {
  getAge: function() { return this.age; },
  setAge: function(age) { this.age = age; }
}

// Дочірній клас. Наслідується від NamedThing та AgedThing,
// а також визначає адресу
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('Боб', 25, 'Нью-Йорк');

console.log('getAge ' + (('getAge' in bob) ? 'належить' : 'не належить') + ' Бобу');
// getAge не належить Бобу

console.log("Вік Боба: " + bob.getAge());
// Вік Боба: 25

console.log('getName ' + (('getName' in bob) ? 'належить' : 'не належить') + ' Бобу');
// getName не належить Бобу

console.log("Ім'я Боба: " + bob.getName());
// Ім'я Боба: Боб

console.log('getAddr ' + (('getAddr' in bob) ? 'належить' : 'не належить') + ' Бобу');
// getAddr належить Бобу

console.log("Адреса Боба: " + bob.getAddr());
// Адреса Боба: Нью-Йорк

Специфікації

Не є частиною жодних специфікацій. Ця функціональність була прибрана, дивіться bug 683218.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
__noSuchMethod__
DeprecatedNon-standard
Chrome No support NoEdge No support NoFirefox No support 1 — 43IE No support NoOpera No support NoSafari No support NoWebView Android No support NoChrome Android No support NoFirefox Android No support 4 — 43Opera Android No support NoSafari iOS No support NoSamsung Internet Android No support Nonodejs No support No

Legend

No support  
No support
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

Мітки документа й учасники

Зробили внесок у цю сторінку: DariaManko
Востаннє оновлена: DariaManko,