Daniel B. Davis
Daniel B. Davis

Reputation: 99

Why the strange duplication in Javascript instance objects?

While using Javascript for some fun, I ran into a morass of difficulties surrounding classes and objects. I thought I got that it is not Java, nor c++. Finally, I took my problems into a smallish example to study this.

Running the example produces output:

>>>>>> keys aprop,bprep,cprep,dprop,bprop,cprop.

I expected output:

>>>>>> keys aprop,bprep,cprep,dprop.

If duplication, why are not aprop and dprop also duplicated? I had thought that by using getOwnPropertyNames I prevented prototype keys. Is there a way to fix this short of comparing each key to eliminate duplicates?

<script>

var objList = [];


class TestObj {
    constructor(aprop, bprop, cprop) {
        this.aprop = aprop;
        this.bprep = bprop;
        this.cprep = cprop;
        this.dprop = 0;
    }
    getAprop() { return aprop; }
    getBprop() { return bprop; }
    getCprop() { return cprop; }
    getDprop() { return dprop; }

    setAprop(arg) { aprop = arg; }
    setBprop(arg) { bprop = arg; }
    setCprop(arg) { cprop = arg; }
    setDprop(arg) { dprop = arg; }
}

function create() {
    putList();
    var t1 = objList[1];
    alert("fromlist "+t1);

    var keys = Object.getOwnPropertyNames(t1);
    console.log(">>>>>> keys "+keys);
}

function putList() {    
    onlist(1, "one" [1]);
    onlist(2, "two", [2, 2]);
    onlist(3, "three", [3, 3, 3]);
}
function onlist(a, b, c) {
    var item = new TestObj();
    item.aprop = a;
    item.bprop = b;
    item.cprop = c;
    objList.push(item);
}


create();

</script>

Upvotes: 0

Views: 73

Answers (1)

Ry-
Ry-

Reputation: 225044

I hope this is actually your question. Anyway, here goes:

First, a minimal example:

function Foo() {
    this.bar = 0;
}

Object.keys(new Foo)

The result of this expression is ["bar"] instead of [] because setting properties in a constructor is no different from setting them anywhere else. They’re not on the prototype just by virtue of being in a constructor. This would work:

function Foo() {}
Foo.prototype.bar = 0;

Object.keys(new Foo)

Now bar is on the prototype, and Object.keys, which only lists own property names, returns [] for a Foo instance. This isn’t usually what you want, though; assigning to bar on an instance will still create a new own property, and if it were mutable, then mutating it would affect all instances of Foo.

Is there a way to fix this short of comparing each key to eliminate duplicates?

Don’t loop over properties in the first place.

… and on the off-chance you really mean “duplicates”, note that you spelled them differently: “bprep” and “cprep” vs. “bprop” and “cprop”.

Upvotes: 3

Related Questions