最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

inheritance - JavaScript: Why does the Object.hasOwnProperty method behave like this? - Stack Overflow

programmeradmin0浏览0评论

My understanding is that the Object.hasOwnProperty method checks if the object has a property name of it's own, meaning a non-inherited property. That would mean that the function should return false whenever the property a. doesn't exist, or b. if it's inherited.

Correct me if I'm wrong, but unless this doesn't use classical inheritance, doesn't bar inherit from Foo in the code below? Why is the hasOwnProperty method returning true when the propname property is an inherited property? What did I get wrong here?

Also, how would I use the hasOwnProperty on the Foo object? The code here returns false when checking the the Foo object.

function Foo() {
    this.propname = 'test';
}

var bar = new Foo();

console.log(bar.hasOwnProperty('propname')); // returns true
console.log(Foo.hasOwnProperty('propname')); // returns false

My understanding is that the Object.hasOwnProperty method checks if the object has a property name of it's own, meaning a non-inherited property. That would mean that the function should return false whenever the property a. doesn't exist, or b. if it's inherited.

Correct me if I'm wrong, but unless this doesn't use classical inheritance, doesn't bar inherit from Foo in the code below? Why is the hasOwnProperty method returning true when the propname property is an inherited property? What did I get wrong here?

Also, how would I use the hasOwnProperty on the Foo object? The code here returns false when checking the the Foo object.

function Foo() {
    this.propname = 'test';
}

var bar = new Foo();

console.log(bar.hasOwnProperty('propname')); // returns true
console.log(Foo.hasOwnProperty('propname')); // returns false
Share Improve this question edited Apr 12, 2015 at 9:04 thefourtheye 240k53 gold badges465 silver badges500 bronze badges asked Apr 12, 2015 at 9:03 shmulishmuli 5,1926 gold badges35 silver badges64 bronze badges 4
  • The this on line 2 === bar, no prototype properties are set here. Add prototype ones by setting Foo.prototype.propname = ... – Douglas Commented Apr 12, 2015 at 9:07
  • 1 Bar is an instance of Foo, rather than a descendant. – joews Commented Apr 12, 2015 at 9:07
  • @Douglas can you please elaborate? Why does this require a prototype at all? The method is checking up the property... – shmuli Commented Apr 12, 2015 at 9:13
  • 1 I've elaborated a bit in an answer below, but the point is that 'propname' is not an inherited property, the prototype needs to get involved somewhere for there to be inherited properties. – Douglas Commented Apr 12, 2015 at 9:20
Add a ment  | 

5 Answers 5

Reset to default 5

The stumbling point here is that Javascript uses prototypal inheritance. What you're seeing there isn't actually inheritance at all.

hasOwnProperty will return false if the property:

  1. Does not exist.
  2. Exists but only on the prototype chain.

The 'class' in your code is nothing to do with inheritance at all, it's just a function which sets some properties on an object.

That object happens to be an instance of a new empty object, because you called the function with the new keyword, which is probably where the confusion is ing from.

Imagine rewriting the function as this:

function foo() {
  var bar = {};
  bar.propname = 'test';
  return bar;
}

var baz = foo();

Would you expect baz.hasOwnProperty('propname') to return true? Absolutely, because we explicitly defined the property on the object.

The alternative way to declare the property would have been to declare it on Foo's prototype.

function Foo() {
  this.bar = 'baz';
}

Foo.prototype.propname = 'test';

var baz = new Foo();

baz.propname; // 'test'
baz.hasOwnProperty('propname'); // false

Again, the magical stuff happening here is all down to the new keyword. When you call a function with new the function assigns the value of this to be a new object and sets the prototype of that object to be the same as the prototype of the function you are calling.

Maybe the easiest way of explaining this is that there is a hasOwnProperty method on bar, but if you call bar.hasOwnProperty('hasOwnProperty') it will return false.

This is because the hasOwnProperty method lives at the very top of the prototype chain, on Object.prototype. Every object in Javascript inherits from here, which is why every object will have a hasOwnProperty method.

There's a good article on why new makes object oriented programming difficult in Javascript.

The initial code sample is equivalent to:

function Foo() {
}

var bar = new Foo();
bar.propname = 'test';

console.log(bar.hasOwnProperty('propname')); // returns true
console.log(Foo.hasOwnProperty('propname')); // returns false

This is why bar.hasOwnProperty('propname') returns true (the property has been explicitly set on the bar object), and Foo.hasOwnProperty('propname') returns false (the property has not been set on Foo at all, neither on the Foo object itself nor the prototype).

The hasOwnProperty check is normally used like this:

function Foo() {
    this.propname = 'test';
}
Foo.prototype.inheritedprop = 'test';

var bar = new Foo();

console.log(bar.hasOwnProperty('propname')); // returns true
console.log(bar.hasOwnProperty('inheritedprop')); // returns false

No, propname is actually set on the instance of Foo that is created by new, based on Foo.prototype (that is this). Another approximation of the constructor pattern makes it clear(er) what is going on:

var FooPrototype = {};
var bar = Object.create(FooPrototype);
bar.propname = "test";

When you first wrote Foo, you simply defined a function to be used later.

The "bar" instantiates that function and essentially activates everything inside of it.

Check out this fiddle with these console.logs

console.log(Foo)
console.log(bar)

https://jsfiddle/7pzwcrjo/

You first have to instantiate a new object of the Foo class.

This JS bin further illustrates that point: http://jsbin./zaredowive/2/edit?js,console,output

As you can see the constructor is only called when you instantiate a new object of class Foo which in this case is a variable called bar. You are calling the hasOwnProperty on the function Foo. This function holds no properties.

发布评论

评论列表(0)

  1. 暂无评论