Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Apple JavaScript Coding Guidelines (developer.apple.com)
35 points by olalonde on Oct 31, 2010 | hide | past | favorite | 24 comments


This is a really terrible guide. I just skimmed it and found several major errors:

1. It's pretty well accepted that constructors should be capitalized. This is a minor style problem compared to everything else.

2. The entire section on "freeing" objects is just wrong. Not going to bother explaining why.

3. This is wrong:

   MyChildObject.prototype = MyParentObject.prototype;
Your entire inheritance tree will share a prototype, and adding a property to one constructor's prototype will add it to all of them, even the parents. You need to do something like "MyChildObject.prototype = new MyParentObject;" or "MyChildObject.prototype = Object.create(MyParentObject.prototype);"

4. The copying section contains a for-in loop without a obj.hasOwnProperty(name) guard.


"This is a really terrible guide." would be just enough to sum up this guide. If you're JavaScript newbie just skip it all along and spend that saved time on reading anything from someone like Douglas Crockford.


It would be great if you would submit this feedback on the document using the link at the bottom. Based on personal experience, Apple fixes bad documentation when it is reported.


So if you are reading this and wondering "Then where can I get a decent style guide?" perhaps try this one instead: http://google-styleguide.googlecode.com/svn/trunk/javascript...


"To create a new member function, create a new anonymous function and assign it to the prototype property of the object. "

I prefer not to use anonymous function. I will use named function so that my stack trace is comprehensible when I am debugging.

  myObject.prototype.memberMethod = function()
  {
    // code to execute within this method
  }
becomes

  myObject.prototype.memberMethod = function memberMethod()
  {
    // code to execute within this method
  }
 
Also, what's up with naming the constructor function as 'myObject'. JS prototypical nature is confusing as is and using an example like this can only make it harder to understand.


Indeed, however you have to be careful about the outer scope that the assignment is happening in (because of IE): http://kangax.github.com/nfe/#jscript-bugs

The other option, if you are on Webkit, is to assign something to the `displayName` property of a function or method. This is explained really well here: http://www.alertdebugging.com/2009/04/29/building-a-better-j...


Yeah, I should have added the warning about JScript bugs. At least the first two bugs listed on that page has been fixed in IE9.


Do you have a link regarding IE9 fixing the NFE bugs? Googling "ie9 named function expression" didn't yield particularly good results. Thanks.


Good if you want to program JavaScript like Java/C++, but bad if you want to understand JavaScript. At first glance I did not find no mention of "functional programing" in JavaScript, it's a real shame cause that's what's JavaScript is good at. And of course using setters and getters is pointless because it will blow up in IE and unless you want to mess with the DOM, there is no real reason to use them.


This made no sense to me at all, but I suspect that I may have a deeper misunderstanding of what it's trying to say:

"Assigning a member function to a prototype should not be confused with assigning an anonymous function to a member variable of a class, which only adds the function to a particular instance of the class"

I thought that by setting this.somefn = function() { blah; }; in the constructor, you are adding the function to the prototype of the object, with the name "somefn". At least, I have implemented a fair amount of code this way and used classical JS inheritance without any apparent issues, I would like to know what the difference is both practically and theoretically.


Lets compare the constructor:

function A () { this.helloWorld = function () {return 'hello world'}; }; a = new A();

vs.

function B () {}; B.prototype.helloWorld = function () {return 'hello world'}; b = new B();

Both constructors achieve the same result - their instances a and b both have the methods helloWorld.

Some of the differences are:

1. With constructor A, whenever you create a new instance, you create a new function, hence you have both performance and memory inefficiencies. With Constructor B, the helloWorld function is created just once, and every instance of B automatically inherits this single instance of the function helloWorld, hence we have performance and memory efficiency.

2. Using inheritance through the prototype of the constructor functions also gives more flexibility and simplicity in sharing common functions and modules.


As v413 wrote, the main difference is how the function is linked to the instance. If you define a member function inside the constructor, that member function is assigned to each and every object separately. The function code is not shared across all instances. This is extremely unintuitive if you are coming from a statically typed OOP language like Java/C#. To get a behavior similar to what Java/C# gives you, you should use prototype.

To demonstrate the concept, I created this code example:

http://jsbin.com/utuso3/edit [Click on 'Preview' button to run the example code]

I hope that made sense.


Thanks (and to v413), this does make sense. I hadn't thought it through that each call to the constructor will create a new function object, which was pretty apparent once stated and I re-examined the code.


It’s slightly concerning that Apple use the word "class" in this document. JavaScript has no concept of "class".


But people know what you mean when you say it. It's a style guide, not a language definition.


Pretty simple, but a couple flaws: #1 - delete should only be used on properties. #2 - The example for inheritance is not quite right as the constructor member and the instanceof relationship no longer works as it should.


From the toolkits: "JavaScript toolkits enhance productivity but often carry a significant memory footprint that may slow down your JavaScript application. When using a toolkit, try to reduce the toolkit’s footprint to just the APIs that you use in your application."

This somewhat hints to me that Apple will come out with a framework that allows more modular includes or compiles similar to closures system. This is somewhat a hit to jQuery's "all-in-one" setup.


Looks pretty sparse and as everyone has said, not the best out there. MDC probably still has the best 'official' documentation thus far.


I don't think the intent is to really be a reference for javascript methods, at least for now. Apple releases "Coding Guidelines" as more of a style guide and suggested patterns.


As a designer first and foremost, I've only recently discovered using getter/setter JavaScript functions as a way of faking MVC. It's definitely something worth looking into if you can't warrant the use of a full library like BackboneJS.


Sorry, but I don't follow - what has using getter/setter to do with MVC?


Oops, sorry I never follow this up.

What libraries like Backbone all have in common at the core is that they use setter methods to trigger custom bound listeners/events . When these custom events are fired, they update the multiple variables/objects that are bound directly to them. For someone who is learning JavaScript OOP for the first time on my current project, this makes a lot of sense and seems pretty exciting.


Why does it require JavaScript to load a script about JavaScript?


Probably because people who are interested in reading about JS probably have JS-enabled browsers and aren't using NoScript.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: