Skip to content

Instantly share code, notes, and snippets.

@creationix
Forked from brianleroux/wtftim.js
Created August 11, 2010 20:38
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 creationix/519700 to your computer and use it in GitHub Desktop.
Save creationix/519700 to your computer and use it in GitHub Desktop.
new is evil!
var Person = function( name ){ this.name = name };
Person.create = function(name) { return new Person(name) };
Brian = new Person('brianleroux');
Tim = Person.create('tim');
// Lame, I would do this one of three ways depending on how it will be used
// If the example really was this simple and there was nothing else involved,
// I would use object literals. No need to overcomplicate things
Brian = {name: "brian"};
Tim = {name: "tim"};
// Assuming there was a reason for more complicated encapsulation, the "best" in some ways
// is a closure that returns objects. Then you can have true private functions and variables
// and there is no need for "this" and "bind" all over the place.
function createPerson(name) {
return {name: name};
}
Brian = createPerson('brian');
Tim = createPerson('tim');
// However, sometimes you need raw speed, or want to inherit from another object.
// In that case prototypal objects are simple and perfect.
// Make a prototype of your objects (aka class)
var Person = {};
// And make a constructor factory that creates these things for you
function createPerson(name) {
var person = Object.create(Person);
person.name = name;
return person;
}
Brian = createPerson('brian');
Tim = createPerson('tim');
// Also you can put the initialize code in the prototype itself so that it can be inherited later on.
var Person = {
initialize: function (name) {
this.name = name;
}
};
Brian = Object.create(Person);
Brian.initialize('brian');
Tim = Object.create(Person);
Tim.initialize('tim');
// And a "subclass" of Person is the exact same thing as an "instance" of Person.
// You simply inherit and specialize
Programmer = Object.create(Person);
Programmer.hobby = "hack";
@SlexAxton
Copy link

You are just using a shorthand for new Object() when you write {}

@creationix
Copy link
Author

Yes it's sad that the standard library (Object, Date, RegExp, ...) are all constructor based. I'm saying we shouldn't continue this confusing concept.

@creationix
Copy link
Author

Though it could be said it's shortcut for Object.create(Object.prototype) since the Object constructor doesn't do anything.

@SlexAxton
Copy link

Assuming it was ECMA5 I spose you're right, but that was certainly an afterthought...

@creationix
Copy link
Author

And "new" can be implemented in pure ES5 even if it wasn't part of the langauge.

new Foo(1, 2, 3)
// is the same as
Foo.call(Object.create(Foo.prototype), 1, 2, 3)

@brianleroux
Copy link

The only diff I'm really seeing here is more noise for the same result. Gotta love those patterns!

@creationix
Copy link
Author

Yeah, I'm not against the patterns, I'm against the magical "new" syntax that confuses newbies. It looks simple and class based, but it's not!

Saying function A inherits from function B really means that function A has a property called "prototype" that inherits from another object that function B happens to point to also via "prototype" and "instances" of function A are really just objects that inherit from A's prototype. Tell me that's not confusing!

@brianleroux
Copy link

I dunno. At this point, it makes sense to me. Its tough, bc I sorta like how: new Whatever() reads in some cases but perhaps that is a C hangover. ;P

Been finding myself using obj literals when I need a singleton and new Whatever()'s for, well, things that I want to treat as a type. Looking at this syntax does make me sorta puke a little in my mouth. Not that it matters: eventually we will get over all this OO bs and start using a lisp variants!

@DmitryBaranovskiy
Copy link

new Foo(1, 2, 3)
// is the same as
Foo.call(Object.create(Foo.prototype), 1, 2, 3)

It is not the same, but this is the same:
var a = new Foo(1, 2, 3);
// is the same
var a = Object.create(Foo.prototype, {
constructor: {
value: Foo,
enumerable: false
}
});
var b = Foo.call(a, 1, 2, 3);
if (b === Object(b)) a = b;

@creationix
Copy link
Author

Good point Dmitry, it's so complicated what all "new" does, I can't even remember everything.

@DmitryBaranovskiy
Copy link

var a = new new new new new new function(){ return arguments.callee;}

new is fun, but way too confusing.

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