2014-10-20 2 views
3

Я искал много на Google, но не удалось найти, где я искал:JavaScript hasOwnProperty против TYPEOF

Benefit of using Object.hasOwnProperty vs testing if Property is undefined

jsperf speedtest

How to determine if Native JavaScript Object has a Property/Method?

.. и много других сайтов, но это не то место, где я ищу. Мой настоящий вопрос:

Почему hasOwnProperty не найти способ в его суперклассе (прототипе)? И почему кто-то даже использует hasOwnProperty? Он намного медленнее, чем typeof, и он не работает, если вы работаете с наследованием.

.. второй вопрос:

this В вопросе Барни отвечает, что вы должны использовать if ('property' in objectVar), чтобы проверить, если свойство существует, но не объясняет, почему. Кто-нибудь знает, почему вы использовали бы эту структуру?

var objA = function(){}; 

objA.prototype.alertMessage = function(){ 
     return 'Hello A'; 
}; 

var objB = function(){ 
    this.hello = function(){ 
     return 'hello'; 
    }; 
}; 

// Inheritance 
objB.prototype = Object.create(objA.prototype); 
objB.prototype.constructor = objA; 

var test = new objB(); 

if (test.hasOwnProperty("alertMessage")){ 
    console.log("hasOwnProperty: " + test.alertMessage()); 
} 

if (typeof test.alertMessage === "function"){ 
    console.log("typeof: " + test.alertMessage()); 
} 

if (test.hasOwnProperty("hello")){ 
    console.log("hasOwnProperty: " + test.hello()); 
} 

if (typeof test.hello === "function"){ 
    console.log("typeof: " + test.hello()); 
} 

Check out the jsFiddle

+2

'typeof' и' hasOwnProperty' не связаны. Оператор 'in' используется для проверки свойств в цепочке прототипов, тогда как' hasOwnProperty' проверяет только непосредственно на этом объекте. Если вы заботитесь о производительности с помощью 'typeof' /' hasOwnProperty', самым быстрым способом является, вероятно, просто использовать оцененное значение (поскольку 'undefined' оценивается как' false'), например. 'if (test.alertMessage)' – Johan

ответ

7

Есть целый ряд причин, почему один использует (и в некоторых случаях имеет использовать) hasOwnProperty, и почему его поведение, что это такое:

  • As название предполагает, hasOwnProperty проверяет, не проверен ли объект, на котором вы тестируете принадлежит имущество с заданным именем. Если он унаследовал метод/свойство от другого объекта (его прототип), то владелец этого свойства не является объектом, а его прототипом. Таким образом, объект не имеет собственного свойства, так как X
  • typeof будет работать большую часть времени, но объект может выглядеть примерно так: var o = {foo: undefined}. Использование typeof на o.foo даст "undefined", конечно, но объект делает собственный свойство foo
  • используя if ('properyname' in object) обходной путь, который сочетает в себе лучшее из обоих миров: в случае o = {foo: undefined}; он будет оценить, правда, без накладные расходы на поиск метода hasOwnPropery (который является свойством Object.prototype) или вызов функции с привязкой контекста и все такое. Он также найти свойства в цепи прототипов

Так считают эти примеры:

var o = {foo: undefined, 
    toString: undefined};//overwrite inherited method 
console.log(typeof o.foo);//undefined 
console.log(typeof o.toString);//undefined 
console.log(o.hasOwnProperty('toString'));//true 
delete(o.toString); 
console.log(typeof o.toString);//function 
if ('valueOf' in o) 
    console.log(o.valueOf === Object.prototype.valueOf);//true 
if ('foo' in o) 
    console.log(o.foo);//undefined 

Другая важная вещь, чтобы отметить, что Ваше заявление о hasOwnProperty не работает, когда дело с наследованием это просто неправильно , Каждый объект, который вы используете в JS, наследуется, по крайней мере, от одного прототипа. Важно понимать, понимать и уважать это. Если вы зацикливаете объект, рекомендуется убедиться, что вы на самом деле итерации по свойствам, принадлежащим самому объекту.Таким образом, это не редкость увидеть:

for (p in obj) 
{ 
    if (obj.hasOwnProperty(p)) 
     //process property 
} 

Это, чтобы избежать код, который перебирает все свойства в цепочке прототипов, возможно, пачкая супер объект

if (!Object.prototype.hasProperty) 
{//dirty check ;-P 
    Object.prototype.hasProperty = (function(OP) 
    { 
     return function(name) 
     { 
      //typeof for speed: if value is not undefined, return true 
      if (typeof this[name] !== 'undefined' || this.hasOwnProperty(name)) 
       return true; 
      if (this === OP)//we've just checked the Object.prototype, found nothing, so return false 
       return false; 
      return Object.getPrototypeOf(this).hasProperty(name);//check prototype 
     }; 
    }(Object.prototype));//OP is object prototype 
} 
+0

Спасибо, что разъяснили это! Первый момент ясен, но было бы более разумно, если бы они добавили метод 'hasProperty';) Остальная часть вашего ответа кажется прекрасной, и я не знал об« неопределенном »трюке». Спасибо, что указали это! – GuyT

+0

@GuyT: вы можете реализовать метод 'hasProperty', который использует' Object.getPrototypeOf' для прохождения через цепочку прототипов до тех пор, пока 'hasOwnProperty' не вернет true или' false' на уровне 'Object.prototype' –

+0

Hmm .. это кажется хорошей реализацией! Я это проверю. Благодарю. – GuyT

Смежные вопросы