Проверьте, имеет ли объект пользовательский прототип?

проще говоря, могу ли я проверить, имеет ли объект пользовательский прототип?

пример:

var A = function() {};

var B = function() {};

B.prototype = {

};

// Pseudocode
A.hasUserPrototype(); // False
B.hasUserPrototype(); // True

это возможно?

3 ответов


предполагая, что вы хотите узнать, является ли объект экземпляром функции пользовательского конструктора, вы можете просто сравнить его прототип с Object.prototype:

function hasUserPrototype(obj) {
    return Object.getPrototypeOf(obj) !== Object.prototype;
}

или если вы поддерживаете constructor свойства правильно:

function hasUserPrototype(obj) {
    return obj.constructor !== Object;
}

это будет работать в браузерах, которые не поддерживают Object.getPrototypeOf.

но оба решения будут возвращать true также для других собственных объектов, таких как функции, регулярные выражения или даты. Чтобы получить "лучшее" решение, вы можете сравнить прототип или конструктор со всеми собственными прототипами / конструкторами.


обновление:

если вы хотите проверить, является ли функции задано пользователем prototype значение, тогда я боюсь, что нет способа обнаружить это. Начальное значение - это просто простой объект со специальным свойством (constructor). Вы мог бы проверьте, существует ли это свойство (A.prototype.hasOwnProperty('constructor')), но если человек, который устанавливает прототип сделал это правильно, они правильно добавили constructor свойство после изменения прототипа.


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

если вы просто пытаетесь проверить наличие свойства с именем prototype на объекте вы можете использовать:

a.hasOwnProperty('prototype')

это вернет true для:

a = {
    //the object has this property, even though
    //it will return undefined as a value
    prototype: undefined 
};

это предполагает, что объект не рассматривается как hashmap, где другие свойства, такие как hasOwnProperty были установлены, в противном случае, более безопасным способом проверка наличия свойства:

Object.prototype.hasOwnProperty.call(a, 'prototype')

это можно превратить в общую функцию как:

has = (function (h) {
    "use strict";
    return function (obj, prop) {
        h.call(obj, prop);
    };
}(Object.prototype.hasOwnProperty));

и используется в качестве:

has(a, 'prototype');

для прототипа объекта будет определено:

typeof A.prototype == "undefined" // true
typeof B.prototype == "undefined" // false