FOO
FOO

Reputation: 612

JavaScript objects and getter properties

Can't figure this out. How come I get NaN and null for volume1 and volume2 properties?

undefined = ''[0];

function Set(defaults) {
    $.extend(this, {
    	repCount: undefined,
        weight: undefined,
	    get volume1() {
    		return this.repCount * this.weight;
    	}
    });
    
    if (defaults) {
    	$.extend(this, defaults);
    }
}

$.extend(Set.prototype, {
    get volume2() {
    	return this.repCount * this.weight;
    }
});

var firstSet = new Set({
    weight: 135,
    repCount: 8
});

document.write(JSON.stringify(firstSet));
document.write("<br />");
document.write(firstSet.volume2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Views: 183

Answers (4)

xsnvt
xsnvt

Reputation: 61

Did some debugging and I saw that your getter method was using the instance of "undefined" to multiple the two in your constructor. So undefined * undefined would return NaN. I changed the way the script constructs Set objects to get it to work, it's now returning a number as properties of the object set in the constructor and don't have a default of undefined.

You can see that it's doing what I'm describing by setting your document.write to get volume1, changing your getter to return this.repCount, and setting repCount to 0, or undefined, as i've done here:

undefined = ''[0];

        function Set(defaults) {
            $.extend(this, {
                repCount: 0,
                weight: 0,
                get volume1() {
                    return this.repCount;
                }
            });

            if (defaults) {
                $.extend(this, defaults);
            }
        }

        $.extend(Set.prototype, {
            get volume2() {
                return this.repCount;
            }
        });

        var firstSet = new Set({
            weight: 135,
            repCount: 8
        });

        document.write(JSON.stringify(firstSet));
        document.write("<br />");
        document.write(firstSet.volume2);

Here's the working code:

        undefined = ''[0];

        function Set(weight, repCount) {
            this.weight = weight;
            this.repCount = repCount;


            $.extend(this, { //it using the current instance as the return 
                get volume1() {
                    return repCount * weight;
                }
            });


        }

        $.extend(Set.prototype, {
            get volume2() {
                return this.weight;
            }
        });

        var firstSet = new Set(135, 8);

        document.write(JSON.stringify(firstSet));
        document.write("<br />");
        document.write(firstSet.volume1);

Upvotes: 2

Alvin Thompson
Alvin Thompson

Reputation: 5448

As @pkyeck mentioned, jQuery's extend does not copy getters/setters. You'll have to add those properties afterwards.

For volume1 you can try this:

Object.defineProperty(this, "volume1", {
  get: function() {
    return this.repCount * this.weight;
  }
});

For volume2:

var p = Set.prototype;
Object.defineProperty(p, "volume2", {
  get: function() {
    return this.repCount * this.weight;
  }
});

Upvotes: 1

Slava Shpitalny
Slava Shpitalny

Reputation: 4195

Object.defineProperty(Set.prototype, "volume2", {
    get: function () {
        return this.repCount * this.weight;
    },
    enumerable: true,
    configurable: true
});

Upvotes: 0

Philipp Kyeck
Philipp Kyeck

Reputation: 18850

jQuery's extend does not copy getter/setter - https://bugs.jquery.com/ticket/6145

Without the get it kind of works:

function Set(defaults) {
    $.extend(this, {
        repCount: undefined,
        weight: undefined,
        volume1: function() {
            return this.repCount * this.weight;
        }
    });

    if (defaults) {
        $.extend(this, defaults);
    }
}

$.extend(Set.prototype, {
    volume2: function() {
        return this.repCount * this.weight;
    }
});

var firstSet = new Set({
    weight: 135,
    repCount: 8
});

document.write(JSON.stringify(firstSet));
document.write("<br />");
document.write(firstSet.volume2());

Upvotes: 1

Related Questions