-
-
Save nzakas/4137558 to your computer and use it in GitHub Desktop.
/* | |
* 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 |
person = { name: person.name, sayName: function () { console.log(this.name) } }
person = Object.create(person, { sayName: { value: function () { return this.name } } })
person = { sayName: function(){ console.log(this.name) }
Object.prototype.sayName = function () { console.log(this.name); };
err I mean: person = Object.create(person, { sayName: { value: function () { console.log(this.name) } } })
@Benvie - congratulations, you win! Bonus for solving it the way that I would've solved it. :-)
Great answers everyone else!
Object.prototype.sayName = function () { return this.name };
I think I like the sheer brute-forcery of your first answer @Benvie
I have a tendency to brute force things. When the browser gives me ES3, I make a better JS engine.
Object.prototype.sayName = function() {
console.log(this.name);
};
Object.prototype.sayMyName = function() {
console.log(this.name);
};
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,
- define a wrapper function
- invoke it.
This code runs (fiddle here):
function wrap(inner){
return {
sayName: function(){
console.log(inner.name)
}
}
};
person = wrap(person);
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 :)
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;
@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.
@nzakas Umm! Then this could be a good solution too.
person.__proto__.sayName= function(){ console.log( this.name); }
Object.prototype.sayName = function(){ console.log(this.name) }