Related
1 - Method Chaining
I really love the way you can call functions without polluting your code with brackets, but the following inconsistency really bothers me;
$(this).attr("id").data "foo"
Method chaining like this pretty much requires me to use brackets up till the last method in the chain, this seems pretty inconsistent and makes my OCD sense tingle like crazy.. am I miss-understanding something here? Is there a more consistent but clean approach (ie. aside from reverting to using brackets everywhere).
2 - Compiler config?
I use coffee --watch to have it automatically compile the files, however the --help shows very few arguments I can give to change it's behaviour. For one thing I'd like to change the tab size of the resulting javascript. Is there any way to do this?
1. Chaining
No, it really isn't much cleaner than javascript, as far as syntax goes. And lots of people are complaining about it. I think you just have to bite the bullet and accept that you have to know javascript to use coffeescript, and that not all the warts of javascript are solved (yet, anyway). Personally I prefer the d3 or jQuery solution of judicious indenting:
$(this)
.attr('id')
.data('foo')
2. Compiler config
There aren't any configs apart from the '--bare' options that I'm aware of. Buts its a compiler, not a formatter. You can send your compiled code all through JS Beautfy (or Uglify for that matter). If you plan on doing this, I highly recommend using a Cakefile. Check out this link for how you can work with the coffee compiler.
No, you need the parentheses if you want to do chaining. I wish it wasn't so, but it is
Not that I know of. What you see in --help is what you get
But CoffeeScript is open source, so you can always hack around with it.
Another solution to your OCD consistency tingling, is to always include parenthesis for method/function arguments. Chaining isn't the only situation where you need to include them. My personal preference would be for the optional omission of parenthesis to be removed from the language but that's probably too extreme for most CoffeeScript users. Instead, I'm choosing to ignore this one "feature" of CS and encouraging my collaborators to do the same. I make the case for it here.
Does anyone know of any tools or easy methods to help re-arrange and organise source code files?
In particular, I am looking for a tool that can take a javascript file, with a number of separate functions, and show me a list of the functions which I can then re-arrange in a more logical order, and have it shuffle the code around to match my new ordering?
Ideally, it would be something that is interactive, rather than a single tool I have to run by command-line, as the order may differ each time.
I'm sure these sorts of tools must exist, but I can never find them whenever I look.
I also suspect that it is something that could be built rather easily by someone with good knowledge of Javascript meta-programming (it might just be a case of 'eval'ing the input, and finding all the functions, then rendering them in a re-orderable list).
I ended up buying WebStorm by JetBrains, which is a commercial product, but it has the ability to see an overview of the file structure, and to reorder statements, including function definitions easily.
This wasn't the reason I bought it, but I am satisfied that it also contains this functionality that I was seeking, so I am going to close this question for now.
There is one, a non-free, editor that I'm aware of so far. I found it when I was duckduckgo'ing months ago.
http://www.yaldex.com/JSFactory_Pro.htm
I've never tried it however.
This isn't about a side-by-side technical comparison, rather about how to "think in jQuery" versus "thinking in Prototype".
I've used Prototype heavily for several years, and jQuery somewhat less heavily until about a year ago when I started doing a lot with it.
With Prototype, I can write some fairly elegant code; my boss once reviewed a large amount of my code and remarked that it was the first Javascript he'd ever found a pleasure to read. I understand - and understood pretty much from the beginning - almost instinctively what Prototype's trying to do, and know how to work with it.
My jQuery code is a lot more, how can I put this, "workmanlike". I feel as if I'm fighting jQuery every step of the way. I have to (try to) force myself to stick with it and not drop down into "native" JS, where I know I could bash out clean cross-browser code more quickly. Working with it more makes it more, not less, frustrating.
It's not (or at least not entirely) a lack of familiarity with the functions available. I'll often know I need to use a given function, but the way in which it's used seems truly bizarre. That's usually a sign that I'm coming at something entirely the wrong way.
The more I think about this, the more I think I'm trying to use jQuery in a Prototype way.
There has to be some blinding flash of light that hasn't happened to me yet. Especially if you've worked a lot with both, what do you find are the most fundamental differences in approach? How do you need to adjust your mindset when switching from one to the other?
Don't be afraid to state the blindingly obvious, because it may just be that blinding flash...
I went through that transformation. The main thing to tell yourself over and over again is that jQuery is, first and foremost, about making DOM manipulation easier and more cross-platform safe. There's no "reduce" (Prototype used to call it "inject", I think) in jQuery. Why? Because the maintainers don't consider it important for the primary task of jQuery.
Thus, the way that Prototype's base object extensions creep into your coding style as you write your code to get your own work done, well, that pretty much doesn't happen in plain ol' jQuery. (See, however, the lovely Underscore.js library for a way to get some of that functionality in a jQuery-friendly way.)
For me, that's made it easier to figure out how to build on jQuery. It's just a different sort of thing. Now, jQuery is very solid and it really does make DOM manipulation and HTML wrangling a lot nicer than what you get from plain Javascript. (I think Prototype does an OK job too, but jQuery is super-focused on the problem.)
The best advice i can give is "Embrace this". In jQ, you're nearly always talking about iterating over a set that is wrapped in the jQuery object. Invoking one of the set's methods performs the method on all the elements of the set, whether its 1 or 100. That method is always going to return the same instance of the set (aside from accessors that get a property). In the context of the interation this is the value of the item in that set youre manipulating - usually the raw DOM Element, but it could be the value of an object property or array item.
Why do you need to think differently? Instead of adapting your style to every framework or language that comes along, why not adapt the framework or language itself to your liking. Then all you'll have to do is be open to the idea that there might be better ways of writing or structuring code than you already know, and when those ways present themselves, objectively analyze and then include them in your repository.
The choice is almost never all or nothing. Both frameworks have great offerings, and you can use techniques from both in harmony for building a great application.
My background is in C and I've picked up PHP, mySQL, HTML, CSS without too much issue.
But I'm finding Javascript/jQuery surprisingly difficult to get right.
Very frustrating.
Why?
It seems to violate a number of traditional programming principles (e.g. variable scope)
Undefined variables seem to appear out of nowhere and already have values associated with them. For example (from the jQuery docs):
$("a").click(function(event) {
event.preventDefault();
$('<div/>')
.append('default ' + event.type + ' prevented')
.appendTo('#log');
});
What exactly is "event"? Do I have to use this variable name? Should I just assume that this object is magically instantiated with the right stuff and I can use any of the methods list at the JQuery API?
There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
It seems like everyday there's some random JS "rule" that comes up that I've never seen before in any of my JS books or tutorials.
What do I need to do to make Javascript/jQuery more deterministic, controlled, and logical to me?
Are there any resources that explain Javascript's quirks/gotchas?
Thanks!
1) It seems to violate a number of traditional programming principles (e.g. variable scope)
You need to declare variables using var, else it will go into the global scope.
2) Undefined variables seem to appear out of nowhere and already have values associated with them (how did this happen?)
This is possibly related to 1) and/or 4).
3) There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
You need to let the handler return false as well. E.g. form onsubmit="return functionname()". You also need to return from the "main" function, not only from a closure (a function inside a function), referring to your previous question. It would only return into the "main" function and continue on.
4) Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Probably the code was executed before the HTML DOM was finished populating. You need to hook on window.onload or $(document).ready() whenever you want to execute stuff during page load.
5) Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
I bet that you're talking about jQuery source? It's just a large library. You should after all not worry about this when debugging. Rather worry about your own code. However, make sure that you're looking at the unminified version of jQuery's source code.
See also:
JavaScript: the bad parts
What should every JavaScript programmer know
Douglas Crockford's "Javascript: The Good Parts" was an invaluable resource. Javascript plays a lot more like Lua, Lisp, or Python than C, it just happens to LOOK like C.
Link provided to Amazon; I snagged mine from O'Reilly.
To be honest, I think you have a good understanding. Some of my hangups were similar. The way that I have been moving on is "well, if that's the way it is, then that's the way it is". Just accept the idiosyncrasies and plow forward. PHP does some of the same things (variables can show up out of nowhere, etc...). Just code the way you want to code and if it works, then great!
Then after you get to that point start breaking out the profiler and see if there's anything that you can optimize.
Here are a couple of things:
If you understand CSS, then jQuery selectors should be easy. As far as the code goes, that's straightforward too if you can deal with chaining and JSON. EDIT: also, the jQuery documentation on everything is EXCELLENT! And There is no shortage of jQuery experts here on SO to help us noobs (and hopefully we can return the favor for newer noobs).
There is a scope to work with. (Basically) anything written outside of a function or object is in global scope. If you are inside of an object or function and use var then that sets the variable's scope
Javascript isn't like a C-based language (C++ or PHP even). It uses prototypes to deal with class/object relationships rather than a subclassing scheme.
The #1 thing that threw me for a loop is that any JS that appears anywhere on the page or that was included in <script> tags is fair game. If you have a global variable in one script, you can use that same variable in a completely different script and it will work. That may be what you mean about variables showing up out of nowhere. Also, there are some DOM based variables that can just "show up" too.
Anyways, I think that if you just plow ahead, you'll get some "AHA" moments. I'm a relative noob to programming, but I continually grow as long as I don't hang up on something that doesn't have too much of an impact on actually making the code run.
It's a language based on prototypal inheritance and is influenced by functional programming languages and the paradigm so it isn't completely just OO/Procedural like other languages. Variables are implied globals unless declared with var.
Please include an example?
return false exits out of the function as with any language's return statement. preventDefault() would be the DOM method to cancel the default behaviour of a link
Javascript is used primarily on the client side. Since there are many user agents, each of them have a different implementation of the DOM, which is very inconsistent, moreso than JS itself. Again, please include a real example to get a definitive answer.
You'll find messy looking code in any language, and maybe your lack of understanding perceives the code as messy, when in fact it isn't so bad. Or maybe you're looking at some minified/obfuscated code.
I recommend http://eloquentjavascript.net/ for learning aspects of Javascript.
Things you'll learn from the link above
lambdas
closures
Prototypal inheritance
Event based programming
Debugging
DOM
"JavaScript: The Good Parts" by Douglas Crockford is a good start
In your case, the appendices ("the bad parts" and "the awful parts") might be the most interesting :)
Crockford's "Javascript: The Good Parts" gives some common JS patterns that help with variable privatization and scoping. This is for javascript in general. For jQuery I just use the API. Also the Yui Theatre videos on javascript are quite good
Javascript can be a little tricky and some of it's functional aspects confuses people. If you actually learn and understand the language you'll find it really useful, most people just randomly start using it and then just hate.
Read javascript the good parts by crockford, it's really helpful: http://javascript.crockford.com/
Also make sure you understand closure. It's a fundamental that people don't get but often use.
In terms of variable scope, there are local and global variables. One of the gotchyas of variable scope can be seen in this example:
var thisIsAGlobalVariable
function anon () {
var thisIsALocalVariable
thisIsAGlobalVariable = 5; //if you don't use the var prefix inside a fn, it becomes global
}
You are finding it difficult because:
javascript has another kind of syntax.
javascript is dificult to debug
javascript has no autocompletion like c# etc) ?or does it
javascript has illogical rules (they become logical once you are known with them)
everything can be done in 1000 ways, and when you search for a solution, you will find 2000 answers :) where c#, php mostly have a good practice function u "should/could" use
However, I started using js/jquery a half year ago, with the same reasoning as you do, and I stuck to it, and now I use it daily to enhance my webapps.
I just love it (especcially jquery). It is a life saver, I know what and where to look, I can do about anything with it.
Everything seems logical.
If I can give you one advice: javascript/jquery is a sour apple, but just hang in there, bit trough and you won't regret it.
also, a loooot of people use it and are always willing to lend a hand if needed (I know I do)
Javascript is tricky. You don't have a compiler watching your back. To compensate, unit testing becomes more important. I've been doing my unit testing with jQuery/QUnit, but I recently started using Jasmine (http://github.com/pivotal/jasmine) and I recommend it 200%. Its a great testing framework.
If you're not familiar with testing, or testing with javascript, I'd highly recommend finding unit tests for other OSS javascript projects (hopefully for code you could use) and seeing how they test it.
With unit tests, you'll make the same mistakes, but catch them much sooner and with less grief. And if your tests are good, the mistakes won't come back after you fix tham.
I don't know how much UI design you have done in C, but the event variable only shows up when it is sent by the caller and the handler needs to, well, handle the object. If you do reading on event object, the confusion in q #2 should go away.
There is no event handling in PHP, so I think you have not came across this issue in the past. JavaScript is a programming language with its own purpose, so it was designed to work for that specific purpose.
Maybe you have to link your code to an HTML onclick="event()" button to fire off as the event.
I understand from this post, that it's an anti-pattern to modify Object's prototype in JavaScript. I was curious, however, if it's widely considered to be an antipattern to modify other 'built-in' prototypes.
For example: say we wanted to add a setPixel(x,y,color) function to CanvasRenderingContext2D - to abstract out the duty of getting the context's image data, setting a pixel to a certain color, and putting the image data back.
CanvasRenderingContext2D.prototype.setPixel = function(x, y, color){
var imgdata = this.createImageData(1,1);
imgdata.data[0] = color.r;
imgdata.data[1] = color.g;
imgdata.data[2] = color.b;
imgdata.data[3] = color.a;
this.putImageData(imgdata,x,y);
};
I haven't tested this code, but you get the idea. Is something like this against 'best practices' ?
I wouldn't do it as it makes it hard to track what is implemented where. It also introduces the risk of two people overriding the same behavior.
Generally, if you are adding a prototype to one of the base objects in JavaScript, you should have a good reason, and there is really no reason to modify Object, since you don't know how to predict what the end result will be of that modification.
I tend to add startsWith, trim and some other functions to String, for example, as these are helper functions, just as adding some functions to Array that exists for Firefox but not IE just makes sense (such as the filter function).
So, adding to the Canvas is fine, but, what if someone is using your library, and using excanvas. Will it cause a problem?
You either may want to explore that, or document that it doesn't work for excanvas, and if you have a small test to show that, please include it, so that if later there is a new version, and your problem disappears people can verify that.
UPDATE:
You will want to do this:
if (!CanvasRenderingContext2D.setPixel) {
...
}
That way, if someone did include one by that name you will not overwrite it, but you will need to handle it gracefully.
Definitely not; if the method is related to the object in this way then it is an elegant solution.
All of these "anti-pattern" suggestions are not to be blindly adopted. No matter what they say, sometimes the best answer is to bite the bullet and go against convention to get things working. This, of course, largely depends on your scenario.
I'm reminded of a situation where days were spent re-organizing code to make the appropriate fix "the right way", when a simple GO TO would have worked great and only taken a couple of minutes to implement. In the end, a bunch of bugs were created because code was changed that did not need to be changed. Am I a fan of GO TO statements? Hell no! But if using one prevents a months worth of headaches, then there is no question.
I don't see any problem with that as long as the functionality or naming does not override what is already there. I know of some that modify the string prototype for Trim functions.
http://www.somacon.com/p355.php
What is funny, C# now has what's called an Extension Method which effectively does the same thing.
Not as itself, but the Ajax library makers might have problems if they cannot rely on the builtin types and their properties. So you could break code that relies on certain behaviour.