Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript getters/setters and extending objects

I'm researching getters and setters in JavaScript and how well they go with spread functions for extending objects, like jQuery's $.extend and Underscore's _.extend. The code setup is as follows:

var test = {
    get size() { return this._size; },
    set size(val) { this._size = val; },
}   

test.size = "LARGE";
console.log(test.size);

//$.extend(test, { get size() { return "MEDIUM"; } });
_.extend(test, { get size() { return "MEDIUM"; } });

console.log(test.size);
test.size = "SMALL";
console.log(test.size);

In Chrome and Firefox I get:

LARGE
MEDIUM
SMALL

Can someone explain me what's happening there? Why after call the original setter, the original getter is also restored?

like image 993
Infeligo Avatar asked Mar 26 '11 23:03

Infeligo


1 Answers

Underscore's extend looks like this:

 _.extend = function(obj) {
   each(slice.call(arguments, 1), function(source) {
     for (var prop in source) obj[prop] = source[prop];
   });
   return obj;
 };

It iterates the source object's properties, adds them to the target object, and then returns the target object. When it copies the size property to the object you're extending, it basically does this:

obj['size'] = source['size']

That is, it uses the new object's getter, but copies only the value returned by that getter. It doesn't transfer the getter itself.

To further demonstrate this, try the following:

var test = {
    get size() { return this._size; },
    set size(val) { this._size = val; },
}   

for (var p in test) {
    console.log(p)
}

Which outputs only:

size

(It doesn't iterate the getters or setters.)

like image 172
Wayne Avatar answered Oct 22 '22 22:10

Wayne