★ wanayoo — archive 1999 https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/noSuchMethodNouvelle recherche | Portail wanayoo
mozilla
Your Search Results

    Object.prototype.__noSuchMethod__

    Не стандартно
    Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

    Сводка

    Свойство __noSuchMethod__ ссылается на функцию, выполняющуюся каждый раз при вызове на объекте несуществующего метода.

    Синтаксис

    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);
    }
    

    Ниже показан пример использования этой идеи.

    // Пример первого базового класса
    
    function NamedThing(name) {
        this.name = name;
    }
    
    NamedThing.prototype = {
        getName: function() { return this.name; },
        setName: function(newName) { this.name = newName; }
    }
    
    // Пример второго базового класса
    
    function AgedThing(age){
        this.age = age;
    }
    
    AgedThing.prototype = {
        getAge: function() { return this.age; },
        setAge: function(age) { this.age = age; }
    }
    
    // Дочерний класс. Наследуется от NamedThing и AgedThing, а также определяет свойство 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('Боб', 25, 'Нью-Йорк');
    
    console.log('getAge лежит ' + (('getAge' in bob) ? 'в' : 'не в') + ' объекте bob');
    console.log('возраст Боба: ' + bob.getAge());
    console.log('getName лежит ' + (('getName' in bob) ? 'в' : 'не в') + ' объекте bob');
    console.log('имя Боба: ' + bob.getName());
    console.log('getAddr лежит ' + (('getAddr' in bob) ? 'в' : 'не в') + ' объекте bob');
    console.log('адрес Боба: ' + bob.getAddr());
    

    Вывод примера будет следующим:

    getAge лежит не в объекте bob
    возраст Боба: 25
    getName лежит не в объекте bob
    имя Боба: Боб
    getAddr лежит в объекте bob
    адрес Боба: Нью-Йорк
    

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

    Не является частью какой-либо спецификации.

    Совместимость с браузерами

    Help improve compatibility tables by filling out this 11 question survey.
    Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
    Базовая поддержка Не поддерживается 1.0 (1.7 или ранее) Не поддерживается Не поддерживается Не поддерживается
    Возможность Android Chrome для Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
    Базовая поддержка Не поддерживается Не поддерживается 1.0 (1.0) Не поддерживается Не поддерживается Не поддерживается

     

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

    На данную страницу внесли свой вклад: Mingun
    Обновлялась последний раз: Mingun,