Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Reading through the following question, I feel the majority of the answers miss the point of why some people (Crockford) choose not to use the "new" keyword. It's not to prevent accidental calling of a function without the "new" keyword.
According to the following article by Crockford regarding prototypal inheritance, he implements an object creation technique that more clearly demonstrates the prototypal nature of JS. This technique is now even implemented in JS 1.8.5.
His argument against using new can be more clearly summed up as:
"This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript's constructor pattern did not appeal to the classical crowd. It also obscured JavaScript's true prototypal nature. As a result, there are very few programmers who know how to use the language effectively."
I don't necessarily consider "new" harmful, but I do agree that it does "obscure JavaScript's true prototypal nature," and therefore I do have to agree with Crockford on this point.
What is your opinion of using a "clearer" prototypal object creation technique, over using the "new" keyword?
You right, using new is considered harmful as it doesn't place enough emphasis on OO in JavaScript being prototypical. The main issue is that acts too much like classical classes and one should not think about class. One should think about Object's and creating new Objects with existing objects as blueprints.
new is a remnant of the days where JavaScript accepted a Java like syntax for gaining "popularity".
These days we do Prototypical OO with Object.create and use the ES5 shim.
There is no need for new anymore.
Before the days of ES5 being commonly implemented (only FF3.6 and IE8 are slacking) we used new because we had little choice. someFunction.prototype was the way to do prototypical inheritance.
I recently wrote up a "nice" demonstration of Object.create although I still need to iron out some kinks in the usage. The important thing is to separate Objects from factory functions.
I don't find that new obscures the prototypical nature of the language for me. Granted I've now spent some years getting to know the language well (having made the mistake originally of diving in and starting writing code without a clue how the language actually worked, to my initial cost).
I find new expressive in a way that prefixing "new" on function names or using a helper function, etc., isn't:
var fido = new Dog(); // Simple, clear
var rover = Dog(); // Very unclear (fortunately people mostly don't do this, but I've seen it)
var scruffles = newDog(); // Clearer, but hacky
var fifi = Object.create(Dog); // (Crockford) Verbose, awkward, not esp. clear
Whether it's prototypical or class-based (and most of that doesn't relate to the new keyword at all), I still think best in terms of functionality grouped together into building blocks (objects or classes or whatever) and then specific objects I can muck about without affecting those building blocks. For me, new as a means of clearly identifying my intent is neither classy or prototypical, it's just clear.
For me, new is just as vital a part of JavaScript as prototypes themselves are, as the wonderfully dexterous functions are. The is is no conflict.
And speaking practically, there are a lot more programmers out there used to using new to create new instances of things than not, and it's a widespread practice in the JavaScript community despite Crockford's efforts (don't misunderstand, I have a lot of respect for Crockford). If I'm staffing up a project, I don't want the retraining hassles.
This is not to say that the way that you define hierarchies of prototypical objects in JavaScript is a thing of beauty and a joy forever. It's a royal pain, especially without the ECMAScript5 enhancements. But define a helper function to help you wire up your hierarchies (whatever you want to call them), and you're done. (See update below.)
[And yes, the whole thing about constructor functions being called without new really is a red herring (you did say you didn't think it was a main point either). You almost never see it happen in the real world. Actually, some of what JavaScript does with that is quite nice (the way String and Number cast, for instance); other parts (what Date does **shudder**) are not so nice...]
As of ES2015 (ES6), creating hierarchies of prototypes and constructors is a breeze, thanks to the new class syntax. No need for helpers anymore.
class Base {
constructor(name) {
this.name = name;
}
greeting() {
return "Hi, I'm " + this.name;
}
}
class Derived extends Base {
constructor(name, age) {
super(name);
this.age = age;
}
greeting() {
return super.greeting() + " and I'm " + this.age + " years old";
}
}
That doesn't mean we want them for everything, of course. I use Object.create to great effect when I need to extend a single object.
My biggest problem with new is that it violates the Open/Closed principle. Because of the way that new manipulates the value of this, constructors are closed for extension, which means if you need to extend it, you must modify it, possibly breaking callers in the process.
Some examples of how factories can be extended that new doesn't allow:
Hide the details of object creation. (The rest of these are examples of why you might want to do that)
Store mutable prototypes and init functions on the factory object, accessible with this. (With new, this always refers to the newly created object).
Extend the pool of possible object types by allowing you to add capabilities to the factory object (extensible polymorphism).
Redefine the meaning of this during instantiation with .call() or .apply() (extending code-reuse).
Return a proxy to a new object in another memory space (iframe, window, different machine).
Conditionally return a reference to an existing object (Actually, you can do that with new and constructors, but then this is meaningless and misleading inside the constructor because a new instance gets allocated and then thrown away if you return something other than a new object).
Enable changes to instantiation strategy without breaking callers.
Note: I'm constantly irritated that I can't easily use any of these strategies with Backbone.js because it forces you to use new, unless you wrap it, but then you close off its standard inheritance mechanism. By way of contrast, I have never found myself irritated that jQuery uses a factory function to instantiate jQuery-wrapped DOM collections.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm referring to MDN's article on JavaScript's 'future reserved words' (for use in the new strict mode) - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Future_reserved_keywords . All the reserved words indicate that JavaScript will possibly follow a non-prototypical inheritance procedure, but what does this mean for already developed applications and modifications? Does anyone know how long these have been 'future reserved words', and whether or not these changes will come to light in the near future or not?
If this isn't the right place, feel free to move it.
Will JavaScript ever become a 'proper' class based language?
Fortunately, NO. It is already a proper language even without being class-based. You will never loose the power to create objects without classes.
I'm referring to MDN's article on JavaScript's 'future reserved words'. All the reserved words indicate that JavaScript will possibly follow a non-prototypical inheritance procedure
No, it's very unlikely that they will give this up. They just want to keep all options open to implement these functionalities, and want to prevent you using this syntax.
Like the Harmony drafts for classes and the current ES6 proposal show, most of these concepts can be implemented well in a prototypal world.
but what does this mean for already developed applications and modifications?
Not much. All changes in EcmaScript try to be as backwards-compatible as possible (remember what all this hassle with strict mode is about?).
Does anyone know how long these have been 'future reserved words', and whether or not these changes will come to light in the near future or not?
The article gives a good overview, I think. You may want to compare ES3, ES5 and the ES6 draft (maybe even earlier versions).
As said above, these are not intended to become "changes". Don't forget that back in the dark old days JavaScript syntax was based on Java, and did inherit its set of keywords. The removal of the Java types, and the addition of new keywords for more powerful concepts, can be seen as setting a direction in the development of EcmaScript.
All the reserved words indicate that JavaScript will possibly follow a non-prototypical inheritance procedure
Not at all. There is a difference between syntax and semantics. Only because you are creating classes with the class keyword in Java, doesn't mean that's what is happening in JavaScript as well. Under the hood, the languages behave differently.
ES6 introduces the class syntax:
class Person() {
constructor(name) {
this.name = name;
}
static create() { }
sayName() {
console.log(this.name);
}
}
Looks like a "class" right? But it's just syntactic sugar for constructor functions and their prototype object:
function Person() {
this.name = name;
}
Person.create = function() { };
Person.prototype.sayName = function() {
console.log(this.name);
};
The static keyword defines the function on the constructor function instead of the prototype (e.g. Person.create instead of Person.prototype.create).
Similarly I could imagine that final will define the property as not writeable and not configurable, at some point.
Bottom line: It's rather unlikely that the fundamental concepts of a language such as JS change completely.
In direct answer to the question, no; this would be a huge fundamental shift in the language.
Most of those have been reserved for ages. One of JavaScript's biggest flaws is NOT that it is a prototypal language, but rather that it in some ways tries to masquerade as a classic OOP language to make it feel more familiar to the old guard.
Neither class based nor is prototype based is inherently wrong or correct; but they are very different. Other prototypal languages have been around for along time, but they had not experienced as much popularity and subsequently familiarity to developers as class based languages.
A great comparative definition I have seen used for this is the following, courtesy of Eric Elliott.
Class based : OOP => Object ORIENTED Programming
Prototypal based : OOP => Object ONLY Programming
There is also a great video available from Eric on Prototypal inheritance here
http://ericleads.com/2013/06/classical-inheritance-is-obsolete-how-to-think-in-prototypal-oo/
And IMHO, one of the best reads over on Prototypal vs Classical inheritence; not even a technical read, but rather more philisophical.
http://carnotaurus.philipcarney.com/post/3010984357/classes-versus-prototypes-some-philosophical-and
We have been debating how best to handle objects in our JS app, studying Stoyan Stefanov's book, reading endless SO posts on 'new', 'this', 'prototype', closures etc. (The fact that there are so many, and they have so many competing theories, suggests there is no completely obvious answer).
So let's assume the we don't care about private data. We are content to trust users and developers not to mess around in objects outside the ways we define.
Given this, what (other than it seeming to defy decades of OO style and history) would be wrong with this technique?
// namespace to isolate all PERSON's logic
var PERSON = {};
// return an object which should only ever contain data.
// The Catch: it's 100% public
PERSON.constructor = function (name) {
return {
name: name
}
}
// methods that operate on a Person
// the thing we're operating on gets passed in
PERSON.sayHello = function (person) {
alert (person.name);
}
var p = PERSON.constructor ("Fred");
var q = PERSON.constructor ("Me");
// normally this coded like 'p.sayHello()'
PERSON.sayHello(p);
PERSON.sayHello(q);
Obviously:
There would be nothing to stop someone from mutating 'p' in unholy
ways, or simply the logic of PERSON ending up spread all over the place. (That is true with the canonical 'new' technique as well).
It would be a minor hassle to pass 'p' in to every function that you
wanted to use it.
This is a weird approach.
But are those good enough reasons to dismiss it? On the positive side:
It is efficient, as (arguably) opposed to closures with repetitive function declaration.
It seems very simple and understandable, as opposed to fiddling with
'this' everywhere.
The key point is the foregoing of privacy. I know I will get slammed for this, but, looking for any feedback. Cheers.
There's nothing inherently wrong with it. But it does forgo many advantages inherent in using Javascript's prototype system.
Your object does not know anything about itself other than that it is an object literal. So instanceof will not help you to identify its origin. You'll be stuck using only duck typing.
Your methods are essentially namespaced static functions, where you have to repeat yourself by passing in the object as the first argument. By having a prototyped object, you can take advantage of dynamic dispatch, so that p.sayHello() can do different things for PERSON or ANIMAL depending on the type Javascript knows about. This is a form of polymorphism. Your approach requires you to name (and possibly make a mistake about) the type each time you call a method.
You don't actually need a constructor function, since functions are already objects. Your PERSON variable may as well be the constructor function.
What you've done here is create a module pattern (like a namespace).
Here is another pattern that keeps what you have but supplies the above advantages:
function Person(name)
{
var p = Object.create(Person.prototype);
p.name = name; // or other means of initialization, use of overloaded arguments, etc.
return p;
}
Person.prototype.sayHello = function () { alert (this.name); }
var p = Person("Fred"); // you can omit "new"
var q = Person("Me");
p.sayHello();
q.sayHello();
console.log(p instanceof Person); // true
var people = ["Bob", "Will", "Mary", "Alandra"].map(Person);
// people contains array of Person objects
Yeah, I'm not really understanding why you're trying to dodge the constructor approach or why they even felt a need to layer syntactical sugar over function constructors (Object.create and soon classes) when constructors by themselves are an elegant, flexible, and perfectly reasonable approach to OOP no matter how many lame reasons are given by people like Crockford for not liking them (because people forget to use the new keyword - seriously?). JS is heavily function-driven and its OOP mechanics are no different. It's better to embrace this than hide from it, IMO.
First of all, your points listed under "Obviously"
Hardly even worth mentioning in JavaScript. High degrees of mutability is by-design. We're not afraid of ourselves or other developers in JavaScript. The private vs. public paradigm isn't useful because it protects us from stupidity but rather because it makes it easier to understand the intention behind the other dev's code.
The effort in invoking isn't the problem. The hassle comes later when it's unclear why you've done what you've done there. I don't really see what you're trying to achieve that the core language approaches don't do better for you.
This is JavaScript. It's been weird to all but JS devs for years now. Don't sweat that if you find a better way to do something that works better at solving a problem in a given domain than a more typical solution might. Just make sure you understand the point of the more typical approach before trying to replace it as so many have when coming to JS from other language paradigms. It's easy to do trivial stuff with JS but once you're at the point where you want to get more OOP-driven learn everything you can about how the core language stuff works so you can apply a bit more skepticism to popular opinions out there spread by people who make a side-living making JavaScript out to be scarier and more riddled with deadly booby traps than it really is.
Now your points under "positive side,"
First of all, repetitive function definition was really only something to worry about in heavy looping scenario. If you were regularly producing objects in large enough quantity fast enough for the non-prototyped public method definitions to be a perf problem, you'd probably be running into memory usage issues with non-trivial objects in short order regardless. I speak in the past tense, however, because it's no longer really a relevant issue either way. In modern browsers, functions defined inside other functions are actually typically performance enhancing due to the way modern JIT compilers work. Regardless of what browsers you support, a few funcs defined per object is a non-issue unless you're expecting tens of thousands of objects.
On the question of simple and understandable, it's not to me because I don't see what win you've garnered here. Now instead of having one object to use, I have to use both the object and it's pseudo-constructor together which if I weren't looking at the definition would imply to me the function that you use with a 'new' keyword to build objects. If I were new to your codebase I'd be wasting a lot of time trying to figure out why you did it this way to avoid breaking some other concern I didn't understand.
My questions would be:
Why not just add all the methods in the object literal in the constructor in the first place? There's no performance issue there and there never really has been so the only other possible win is that you want to be able to add new methods to person after you've created new objects with it, but that's what we use prototype for on proper constructors (prototype methods btw are great for memory in older browsers because they are only defined once).
And if you have to keep passing the object in for the methods to know what the properties are, why do you even want objects? Why not just functions that expect simple data structure-type objects with certain properties? It's not really OOP anymore.
But my main point of criticism
You're missing the main point of OOP which is something JavaScript does a better job of not hiding from people than most languages. Consider the following:
function Person(name){
//var name = name; //<--this might be more clear but it would be redundant
this.identifySelf = function(){ alert(name); }
}
var bob = new Person();
bob.identifySelf();
Now, change the name bob identifies with, without overwriting the object or the method, which are both things you'd only do if it were clear you didn't want to work with the object as originally designed and constructed. You of course can't. That makes it crystal clear to anybody who sees this definition that the name is effectively a constant in this case. In a more complex constructor it would establish that the only thing allowed to alter or modify name is the instance itself unless the user added a non-validating setter method which would be silly because that would basically (looking at you Java Enterprise Beans) MURDER THE CENTRAL PURPOSE OF OOP.
Clear Division of Responsibility is the Key
Forget the key words they put in every book for a second and think about what the whole point is. Before OOP, everything was just a pile of functions and data structures all those functions acted on. With OOP you mostly have a set of methods bundled with a set of data that only the object itself actually ever changes.
So let's say something's gone wrong with output:
In our strictly procedural pile of functions there's no real limit to the number of hands that could have messed up that data. We might have good error-handling but one function could branch in such a way that the original culprit is hard to track down.
In a proper OOP design where data is typically behind an object gatekeeper I know that only one object can actually make the changes responsible.
Objects exposing all of their data most of the time is really only marginally better than the old procedural approach. All that really does is give you a name to categorize loosely related methods with.
Much Ado About 'this'
I've never understood the undue attention assigned to the 'this' keyword being messy and confusing. It's really not that big of a deal. 'this' identifies the instance you're working with. That's it. If the method isn't called as a property it's not going to know what instance to look for so it defaults to the global object. That was dumb (undefined would have been better), but it not working properly in that scenario should be expected in a language where functions are also portable like data and can be attached to other objects very easily. Use 'this' in a function when:
It's defined and called as a property of an instance.
It's passed as an event handler (which will call it as a member of the thing being listened to).
You're using call or apply methods to call it as a property of some other object temporarily without assigning it as such.
But remember, it's the calling that really matters. Assigning a public method to some var and calling from that var will do the global thing or throw an error in strict mode. Without being referenced as object properties, functions only really care about the scope they were defined in (their closures) and what args you pass them.
I just finished Doug Crockford's The Good Parts, and he offers three different ways to go about inheritance: emulation of the classical model, prototype-based inheritance, and functional inheritance.
In the latter, he creates a function, a factory of sorts, which spits out objects augmented with desired methods that build upon other objects; something along the lines of:
var dog = function(params) {
// animal is the 'super class' created
// the same way as the dog, and defines some
// common methods
var that = animal(params);
that.sound = 'bark';
that.name = function () {};
return that;
}
Since all objects created this way will have a reference to the same functions, the memory footprint will be much lower than using when using the new operator, for instance. The question is, would the prototype approach offer any advantages in this case? In other words, are object prototypes somehow 'closer to the metal' that provide performance advantages, or are they just a convenience mechanism?
EDIT: I'll simplify the question. Prototypes vs. their emulation through object composition. So long as you don't require all object instances to get updated with new methods which is a convenience offered only by prototypes, are there any advantages to using prototypes in the first place?
I emailed Doug Crockford, and he had this to say:
[Using the functional approach above vs. prototypes] isn't that much memory. If you have a huge number of objects times a huge number of methods, then you might want to go prototypal. But memories are abundant these days, and only an extreme application is going to notice it.
Prototypes can use less memory, but can have slightly slower retrieval, particularly if the chains are very long. But generally, this is not noticeable.
The instances don't all reference the same functions etc. Each call to "dog" will create a new "name" function instance.
There are many opinions about this, and Crockford's isn't necessarily the right one.
The main disadvantage to modifying the prototypes is that it may make it harder to work with other javascript libraries.
But the disadvantage of Crockford's functional way of creating classes is that you can't add a method or field to all instances of a type as easily.
See Closure: The Definitive Guide for some critical comments on Crockford's view about classes and inheritance in javascript:
http://my.safaribooksonline.com/9781449381882/I_sect1_d1e29990#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE0NDkzODE4ODIvNTE0
Libraries like Dojo, Google Closure Library (which seems to copy Dojo's style), and perhaps YUI have their own class system that seems to be a good middle ground. I like Dojo's system probably the best because it has support for Mixins, unlike Closure. Some other class systems not tied to gui toolkits include Joose, JS.Class, and JavascriptMVC (check out last one esp. if using jquery).
I once created a GUI that was backed by a class that didn't have great event-based support for the information it needed. The GUI implemented a generic interface where an instance of that class is passed in, so I cannot inherit from that class, so I did something similar to prototype-based inheritance, I created a proxy object that wraps the instance of that class when it's passed to my GUI. The proxy intercepts methods of interest that mutate state, and report them as events. The entire GUI then revolved around using these events.
In this case, it would have just been annoying to create a separate class that wraps the passed in instance and reproduces the same interface. This would actually have lead to more overhead (not that it matters) due to creating all the redundant functions.
There was simply no other viable alternative. The only alternatives were:
Create an object that composes the object passed to the GUI (like I mentioned above). This object would then reproduce every function in the original class to implement the same interface, and add events, so it's effectively just the same as the proxy object way.
Have the GUI track state mutation in its passed in object. This would have been a pain and bug prone.
The question is from a language design perspective.
I should explain a little about the situation. I am working on a javascript variant which does not support prototypes, however it is overdue a decent type system (most importantly support for instanceof). The ecmascript spec is not important, so i have the freedom to implement something different and better suited.
In the variant:-
You do not declare constructors with function foo(), rather constructors are declared in template files, which means constructors exist in a namespace (detirmined by the path of the file)
Currently all inheritance of behaviour is done by applying templates which means all shared functions are copied to each individual object (there are no prototypes afterall).
Never having been a web developer, this puts me in the slightly bizarre position of never having used prototypes in anger. Though this hasn't stopped me having opinions on them.
My principal issues with the prototype model as i understand it are
unnecessary littering of object namespace, obj.prototype, obj.constructor (is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?)
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
So to get around these my idea is to have a special operator constructorsof. Basically the principal is that each object has a list of constructors, which occasionally you will want access to.
var x = new com.acme.X();
com.acme.Y(x,[]); // apply y
(constructorsof x) // [com.acme.Y,com.acme.X,Object];
x instanceof com.acme.X; // true
x instanceof com.acme.Y; // true
All feedback appreciated, I appreciate it maybe difficult to appreciate my POV as there is a lot i am trying to convey, but its an important decision and an expert opinion could be invaluable.
anything that can improve my understanding of the prototype model, the good and the bad.
thoughts on my proposal
thanks,
mike
edit: proposal hopefully makes sense now.
Steve Yegge has written a good technical article about the prototype model.
I don't think your issues with the prototype model are valid:
unnecessary littering of object namespace, obj.prototype, obj.constructor
prototype is a property of the contructor function, not the object instance. Also, the problem isn't as bad as it sounds because of the [[DontEnum]] attribute, which unfortunately can't be set programatically. Some of the perceived problems would go away if you could.
is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?
There's no problem with using objects as maps as long as the keys are strings and you check hasOwnProperty().
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
I don't see where the big implementation headache in implementning the prototype chain lies. In fact, I consider prototypical inheritance conceptually simpler than class-based inheritance, which doesn't offer any benefits in languages with late-binding.
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
People who only know class-based oo languages like Java and C++ don't understand JavaScript's inheritance system, news at 11.
In addition to MarkusQ's suggestions, you might also want to check out Io.
It might just be easier to try a few things with practical code. Create the language with one simple syntax, whatever that is, and implement something in that language. Then, after a few iterations of refactoring, identify the features that are obstacles to reading and writing the code. Add, alter or remove what you need to improve the language. Do this a few times.
Be sure your test-code really exercises all parts of your language, even with some bits that really try to break it. Try to do everything wrong in your tests (as well as everything right)
Reading up on "self", the language that pioneered the prototype model, will probably help you more than just thinking of it in terms of javascript (especially since you seem to associate that, as many do, with "web programming"). A few links to get you started:
http://selflanguage.org/
http://www.self-support.com/
Remember, those who fail to learn history are doomed to reimplement it.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I'm finding myself coding a big project in Javascript. I remember the last one was quite an adventure because hacky JS can quickly becomes unreadable and I want this code to be clean.
Well, I'm using objects to construct a lib, but there are several ways to define things in JS, implying important consequences in the scope, the memory management, the name space, etc. E.G :
using var or not;
defining things in the file, or in a (function(){...})(), jquery style;
using this, or not;
using function myname() or myname = function();
defining methods in the body of the object or using "prototype";
etc.
So what are really the best practices when coding in OO in JS ?
Academic explanations really expected here. Link to books warmly welcome, as long as they deal with quality and robustness.
EDIT :
Got some readings, but I'm still very interested in answers to the questions above and any best practices.
Using `var` or not
You should introduce any variable with the var statement, otherwise it gets to the global scope.
It's worth mentioning that in strict mode ("use strict";) undeclared variable assignments throws ReferenceError.
At present JavaScript does not have a block scope. The Crockford school teaches you to put var statements at the beginning of the function body, while Dojo's Style Guide reads that all variables should be declared in the smallest scope possible. (The let statement and definition introduced in JavaScript 1.7 is not part of the ECMAScript standard.)
It is good practice to bind regularly-used objects' properties to local variables as it is faster than looking up the whole scope chain. (See Optimizing JavaScript for extreme performance and low memory consumption.)
Defining things in the file, or in a `(function(){...})()`
If you don't need to reach your objects outside your code, you can wrap your whole code in a function expression—-it's called the module pattern. It has performance advantages, and also allows your code to be minified and obscured at a high level. You can also ensure it won't pollute the global namespace. Wrapping Functions in JavaScript also allows you to add aspect-oriented behaviour. Ben Cherry has an in-depth article on module pattern.
Using `this` or not
If you use pseudo-classical inheritance in JavaScript, you can hardly avoid using this. It's a matter of taste which inheritance pattern you use. For other cases, check Peter Michaux's article on JavaScript Widgets Without "this".
Using `function myname()` or `myname = function();`
function myname() is a function declaration and myname = function(); is a function expression assigned to variable myname. The latter form indicates that functions are first-class objects, and you can do anything with them, as with a variable. The only difference between them is that all function declarations are hoisted to the top of the scope, which may matter in certain cases. Otherwise they are equal. function foo() is a shorthand form. Further details on hoisting can be found in the JavaScript Scoping and Hoisting article.
Defining methods in the body of the object or using "prototype"
It's up to you. JavaScript has four object-creation patterns: pseudo-classical, prototypical, functional, and parts (Crockford, 2008). Each has its pros and cons, see Crockford in his video talks or get his book The Good Parts as Anon already suggested.
Frameworks
I suggest you pick up some JavaScript frameworks, study their conventions and style, and find those practices and patterns that best fit you. For instance, the Dojo Toolkit provides a robust framework to write object-oriented JavaScript code which even supports multiple inheritance.
Patterns
Lastly, there is a blog dedicated to explore common JavaScript patterns and anti-patterns. Also check out the question Are there any coding standards for JavaScript? in Stack Overflow.
I am going to write down some stuffs that I read or put in application since I asked this question. So people reading it won't get frustrated, as most of the answers are RTMF's in disguise (even if I must admit, suggested books ARE good).
Var usage
Any variable is supposed to be already declared at the higher scope in JS. So when ever you want a new variable, declare it to avoid bad surprises like manipulating a global var without noticing it. Therefore, always use the var keyword.
In an object make, var the variable private. If you want to just declare a public variable, use this.my_var = my_value to do so.
Declaring methods
In JS, they are numerous way of declaring methods. For an OO programmer, the most natural and yet efficient way is to use the following syntax:
Inside the object body
this.methodName = function(param) {
/* bla */
};
There is a drawback: inner functions won't be able to access "this" because of the funny JS scope. Douglas Crockford recommends to bypass this limitation using a conventional local variable named "that". So it becomes
function MyObject() {
var that = this;
this.myMethod = function() {
jQuery.doSomethingCrazy(that.callbackMethod);
};
};
Do not rely on automatic end of line
JS tries to automatically add ; at the end of the line if you forget it. Don't rely on this behavior, as you'll get errors that are a mess to debug.
First ought to read about the prototype-based programming so you know what kind of beast you're dealing with and then take a look at JavaScript style guide at MDC and JavaScript page at MDC. I also find best to force the code quality with a tool, ie. JavaScript Lint or other variants.
Best practices with OO sounds more like you want to find patterns than concentrate on code quality, so look at Google search: javascript patterns and jQuery patterns.
Speed up your JavaScript
You might want to check out Secrets of the JavaScript Ninja by John Resig (jQuery). "This book is intended to take an intermediate JavaScript developer and give him the knowledge he needs to create a cross-browser JavaScript library, from the ground, up."
The draft is available through the publisher:
http://www.manning.com/resig/
Douglas Crockford also has some nice JavaScript articles on his homepage:
http://www.crockford.com/
I often feel like the only guy here who uses MooTools for my javascript.
It stands for My Object Oriented Tools, mootools.
I really like their take on OOP in javascript. You can use their class implementation along with jquery too, so you don't have to ditch jquery (though mootools does it all just as well).
Anyway, give the first link a good read and see what you think, the second link is to the mootools docs.
MooTools & Inheritance
MooTools Classes
Here's a book that covers most of the bases:
Object Oriented Javascript for high quality applicatons and libraries