2

I'm sure this is a duplicate, but I couldn't find the right search terms to find an answer.

I'm trying to use hasOwnProperty() to determine if a function exists on an object or not. I know there are other ways to do this, but I want to understand why that method doesn't work the way I was expecting.

I typed this into a Chrome Dev Tools console:

window.hasOwnProperty("getSelection")
<- true

window.getSelection().hasOwnProperty("empty")
<- false

What I don't understand is why hasOwnProperty("empty") returns false, when that method does exist on the Selection object and I can call it.

window.getSelection().empty()  // Returns no errors
ᴇʟᴇvᴀтᴇ
  • 12,285
  • 4
  • 43
  • 66
  • 2
    `"empty" in window.getSelection()` returns true. So, it's inherited, from somewhere down the prototype chain: [hasOwnProperty('getTime') returns false on date object](https://stackoverflow.com/questions/48112458) and [if (key in object) or if(object.hasOwnProperty(key)](https://stackoverflow.com/questions/13632999) – adiga Aug 09 '19 at 09:19

2 Answers2

5

getSelection returns a Selection object instance, which has an internal prototype of Selection.prototype. The prototype has the empty method on it; it's not on the instance itself:

const sel = window.getSelection();
console.log(
  Object.getPrototypeOf(sel) === Selection.prototype,
  Selection.prototype.hasOwnProperty("empty")
);

If you wanted to implement this sort of thing yourself:

class Foo {
  method() {
    console.log('method');
  }
}
const f = new Foo();
f.method();

console.log(
  f.hasOwnProperty('method'),
  Foo.prototype.hasOwnProperty('method')
);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

That's because it's not a property on that object, rather it's inherited. Inherited properties are not the object's own properties, as they come from the constructor or class. Far better is the in keyword:

console.log("getSelection" in window);
console.log("empty" in window.getSelection());
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79