Skip to content

Instantly share code, notes, and snippets.

@nzakas
Created November 23, 2012 22:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nzakas/4137558 to your computer and use it in GitHub Desktop.
Save nzakas/4137558 to your computer and use it in GitHub Desktop.
Contest
/*
* Contest to win one of my books. If you're in the United States, you can choose either
* Professional JavaScript for Web Developers or Maintainable JavaScript and I will send
* you a signed copy. If you're outside the United States, I will send you the PDF version
* of either book. Good luck!
*
* Rules
* 1. Assume this is the only code! Don't worry about real world situations.
* 2. You can use anything defined in ECMAScript 5 to solve the problem (no DOM, BOM, etc.)
* 3. There is more than one correct answer but only the first correct answer wins.
* 4. Post your answer on this gist. Answers received elsewhere (Twitter, email, etc.) don't count.
*/
var person = {
name: "Nicholas"
};
Object.freeze(person);
// Contest: What code goes here so that the next bit of code runs correctly?
person.sayName(); // outputs "Nicholas" to console
Copy link

ghost commented Nov 23, 2012

Object.prototype.sayName = function(){ console.log(this.name) }

@gryzzly
Copy link

gryzzly commented Nov 23, 2012

person = { name: person.name, sayName: function () { console.log(this.name) } }

@rvagg
Copy link

rvagg commented Nov 23, 2012

person = Object.create(person, { sayName: { value: function () { return this.name } } })

Copy link

ghost commented Nov 23, 2012

person = { sayName: function(){ console.log(this.name) }

@johnathanhebert
Copy link

Object.prototype.sayName = function () { console.log(this.name); };

@rvagg
Copy link

rvagg commented Nov 23, 2012

err I mean: person = Object.create(person, { sayName: { value: function () { console.log(this.name) } } })

@nzakas
Copy link
Author

nzakas commented Nov 23, 2012

@Benvie - congratulations, you win! Bonus for solving it the way that I would've solved it. :-)

Great answers everyone else!

@rodrigoalvesvieira
Copy link

Object.prototype.sayName = function () { return this.name }; 

@rvagg
Copy link

rvagg commented Nov 23, 2012

I think I like the sheer brute-forcery of your first answer @Benvie

Copy link

ghost commented Nov 23, 2012

I have a tendency to brute force things. When the browser gives me ES3, I make a better JS engine.

@iamdtang
Copy link

Object.prototype.sayName = function() {
console.log(this.name);
};

@tiagojack
Copy link

Object.prototype.sayMyName = function() {
console.log(this.name);
};

@WinstonFassett
Copy link

I don't think any of the above actually work, because

this 

does not point to

person

Regardless, I would go a little less brute force,

  1. define a wrapper function
  2. invoke it.

This code runs (fiddle here):

function wrap(inner){
    return {
        sayName: function(){ 
            console.log(inner.name) 
        }
    }
};
person = wrap(person);

@WinstonFassett
Copy link

My apologies, I had started with the 4th answer which had produced errors for me. gryzzly and rvagg's solutions both work. I particularly like gryzzly's, and clearly I will be buying your book :)

@tcorral
Copy link

tcorral commented Nov 24, 2012

When you freeze an object is not possible to unfreeze it.
The solution is to create another object.
In my proposal I create a new object with a method sayName and merge all the members of person on the new object, then after all I set person to reference the new object.

var _person = {
  sayName: function()
  {
      console.log(this.name);
  }
};
for (var prop in person) {
   if(person.hasOwnProperty(prop)) {
      _person [prop] = person[prop];
   }
}
person = _person;

@nzakas
Copy link
Author

nzakas commented Nov 26, 2012

@tcorral - you are correct in that you cannot unfreeze an object, but the easiest way to solve the problem is to modify the prototype as in the first answer. The prototype members aren't frozen so you can continue to add new methods to it and those will automatically flow through to the instances.

@tcorral
Copy link

tcorral commented Dec 4, 2012

@nzakas Umm! Then this could be a good solution too.

person.__proto__.sayName= function(){ console.log( this.name); }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment