6

Here i have a code which uses getter and setter to define and fetch a property value.I created an object using a object constructor.I passed the object in a for...in loop.Also used getOwnPropertyNames() method on the object.Here are the results

"fullName" property is accessible in for...in loop

"fullName" is not visible in getOwnPropertyNames() method.That means it is

not a own property

Here i have two basic question.What is an own property? If "fullName" is not a own property then what type of property it is ?

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};
var obj=new Name('al','zami');
for(var i in obj){
   console.log(i); // fullName is here
}
console.log(Object.getOwnPropertyNames(obj)); // fullName is not here
AL-zami
  • 8,902
  • 15
  • 71
  • 130

2 Answers2

9

hasOwnProperty and getOwnPropertyNames refer to properties assigned directly to the object rather than only being accessible through the object's prototype chain. Either this.foo = or bar.foo = count as an own property, because you're assigning to the instance.

"Own properties" are defined in section 4.3.30 of the spec to be:

property that is directly contained by its object

vs an "inherited property," defined (4.3.31) as:

property of an object that is not an own property but is a property (either own or inherited) of the object’s prototype

That is, an "own" property is on the instance, not the prototype.

The biggest impact is with prototypical classes (constructors with some methods and/or static properties). In classical OO terms, getOwnPropertyNames will skip class methods and anything that would have a static keyword.

If you take a look at section 8.12.1 of the spec, it indirectly excludes the prototype. In step #3, the runtime checks the object's own properties for the appropriate property name. However, in section 8.12.2 (referring to getProperty without the "own" qualifier), steps #3-4 describe checking the object's prototype if the property was not found on the object itself.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
ssube
  • 47,010
  • 7
  • 103
  • 140
  • 1
    Notice that even an assignment might not create a property, if there is an inherited setter – Bergi Apr 06 '16 at 16:11
  • 1
    FWIW, http://www.ecma-international.org/ecma-262/6.0/index.html is the current spec ;) – Felix Kling Apr 06 '16 at 16:14
  • @FelixKling I understood the concept like, proto's properties are not a own property of an object. Ok. But while doing inheritance, we will call the parent's constructor by supplying `this` from the child. At that time, the properties of parent(not proto's) will be considered as own properties of child object? Thanks – Rajaprabhu Aravindasamy Apr 06 '16 at 16:20
  • 1
    @RajaprabhuAravindasamy if you mean a `super` call in the child's constructor, then properties assigned by either the parent or subclass' constructor are both own properties. The difference is prototype vs direct. – ssube Apr 06 '16 at 16:21
  • 2
    @RajaprabhuAravindasamy: Since `this` will refer to the child object and the properties are assigned to it, yes. The concept of "own" properties are very simply actually and don't have anything to do with constructors or "where" a property is assigned. Don't let constructors and classes give you the impression that JavaScript is more complex than it is ;) – Felix Kling Apr 06 '16 at 16:23
  • Thanks both of you. The fun part is that I have developed a javascript console app to explore the prototype chain without knowing it all. ;) – Rajaprabhu Aravindasamy Apr 06 '16 at 16:24
1

Object.getOwnPropertyNames returns the property names that are directly on the object. For instance if you add a new property to the object using obj.foo = 'bar'; then "foo" will be included in the object's own properties. fullName isn't a property directly on obj, but it is a property of this object:

{
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
}

which happens to be the internal prototype of obj:

Object.getOwnPropertyNames( Object.getPrototypeOf( obj ) ); // ["fullName"]

The for ...in loop iterates through all enumerable properties in the objects prototype chain, so it will include those properties.

Paul
  • 139,544
  • 27
  • 275
  • 264