2010-02-11 5 views
17

Учитывая следующий код:Как я могу увидеть цепочку прототипов объекта Javascript?

function a() {} 
function b() {} 
b.prototype = new a(); 
var b1 = new b(); 

Мы можем остаться, что a добавлен b «s цепи прототипов. Отлично. И все следующие условия:

b1 instanceof b 
b1 instanceof a 
b1 instanceof Object 

Мой вопрос, что если мы не знаем о происхождении b1 раньше времени? Как мы можем обнаружить членов своей прототипной цепи? В идеале мне нужен массив вроде [b, a, Object] или ["b", "a", "Object"].

Возможно ли это? По-моему, я видел ответ где-то на SO, который описывал, как это узнать, но я не могу, чтобы жизнь меня снова находила.

ответ

2

Вы можете использовать свойство «конструктор» объекта, чтобы найти там прототип, а затем двигаться вдоль него, пока не достигнете конца радуги.

function getPrototypes(o) { 
    return (function gp(o, protos) { 
    var c = o.constructor; 
    if (c.prototype) { 
     protos.push(c.prototype); 
     return gp(c.prototype, protos); 
    } 
    return protos; 
    })(o, []); 
} 

(может быть) (или, может быть, не :-) дать мне сек) (а дерьмо, и я думаю, что это возможно, но игнорировать этот код)

[править] вау это совершенно дует мой разум - эта функция близка, но не совсем правильна; создание цепи прототипов странно, и я чувствую себя страшно и одиноко. Я предлагаю обратить внимание только на удивительную @CMS выше.

+0

'constructor' дает вам функцию-конструктор ближайшего прототипа-предка, который не был унаследован от другого прототипа-конструктора. Это почти никогда не то, что вы хотите. Например, в коде вопроса 'b1.constructor' является' a', а не 'b', и если вы вывели объект' c' из 'b',' c1.constructor' все равно будет 'a'. Обычное эмпирическое правило: не используйте конструктор для чего-либо когда-либо. [eta: lol @ 'scared and lonely' ... да, это одна из тех частей JavaScript, которая предназначена для того, чтобы сбивать с толку вас, делая что-то полезное, но на самом деле это ловушка.] – bobince

+0

Да, я рассмотрите оригинальный вопрос в интересном упражнении, но я никогда не добавлял код, который, как я ожидал, действительно работал. Здесь очень хорошее объяснение: http://mckoss.com/jscript/object.htm – Pointy

7

Ну, прототип связи между объектами ([[Prototype]]) является внутренним, некоторые реализации, такие как Mozilla, отображают его как obj.__proto__.

Метод ECMAScript 5th Edition - это то, что вам нужно, но оно не реализовано прямо сейчас на большинстве движков JavaScript.

Дайте взглянуть на это implementation Джона Resig, он имеет ловушку, он полагается на constructor собственности двигателей, которые не поддерживают __proto__:

if (typeof Object.getPrototypeOf !== "function") { 
    if (typeof "test".__proto__ === "object") { 
    Object.getPrototypeOf = function(object){ 
     return object.__proto__; 
    }; 
    } else { 
    Object.getPrototypeOf = function(object){ 
     // May break if the constructor has been tampered with 
     return object.constructor.prototype; 
    }; 
    } 
} 

Помните, что это не 100% надежное, поскольку свойство constructor изменено на любом объекте.

+2

прямо как что-либо в Javascript, смотрящем на свойства объекта и доверяющий то, что вы получаете, является рискованным :-) – Pointy

+0

Спасибо, но это говорит мне, что 'a' является прототипом' b1', но ничего о 'b'. Как я могу найти, что 'b1' является экземпляром' b'? – pr1001

+0

Возвращение к 'constructor' не просто неверно из-за возможного вмешательства в прототип, с самого начала совершенно неправильно, потому что' constructor' не делает то, что вы думаете (см. Комментарий ниже). Это показывает удивительное незнание базовых функций JavaScript от Resig; ** не используйте этот скрипт **. Однако информация о '__proto__' и' getPrototypeOf' хороша. – bobince

0

Вот отправная точка:

Object.prototype.getConstructorNames=function(){ 
     return Object.keys(window).filter(function(e){ 
      return typeof window[e]==="function" && this instanceof window[e]},this) 
    } 

Конечно, это действительно неполное, но я думаю, что он будет работать в большинстве случаев, и если кто-то хочет добавить к этим они могут.