Looking for Magento 2? Check out the new article: Modifying Magento 2's Javascript.
Because Magento uses object prototype properties for most of it's functionality, it's quite easy to change it's behaviour without editing core files.
This article shows four ways to change the Product.Zoom.prototype.toggleFull
method as defined in js/Varien/product.js
.
Direct prototype override
Product.Zoom.prototype.toggleFull = function() {
// your code
}
Cons: No access to the original method
Using Prototype's addMethods()
Product.Zoom.addMethods({
toggleFull: function() {
// your code
}
})
Cons: Still no access to the original method...
Reference: Class#addMethods
Using Prototype's wrap()
Product.Zoom.prototype.toggleFull = Product.Zoom.prototype.toggleFull.wrap(function(superMethod){
// your code
return superMethod();
});
Pros: You can call the super method
Reference: Function#wrap
OOP subclassing
var MyClass = Class.create(Product.Zoom, {
// add other properties
// redefine the speak method
toggleFull: function($super) {
// your code
// execute original function
return $super();
}
});
Pros: You're not changing the behaviour of Magento's core classes - the code will still have original functionality unless you explicitly tell it to use your class instead. You also have access to the super method.
Cons: Requires you to edit template files. In this case you'll need to change
product_zoom = new Product.Zoom('...');
to
product_zoom = new MyClass('...');
in app/design/frontend/base/default/template/catalog/product/media.phtml
on line 55 (Magento 1.8.1.0).
Reference: Defining classes and inheritance
Conclusion
Wrap seems the best way if you need access to the super method.
Similarly to the Magento backend, consider using your class directly (like the last example) instead of blindly rewriting functionality. This might give you better compatibility with third party modules in the future.
Also, lately I've been using Prototype custom events in my code instead of rewriting functionality where possible. This is very similar to the observer pattern on the server.
Here's an example of fireing a custom event in one of the Onepage checkout functions:
Checkout.prototype.reloadReviewBlock =
Checkout.prototype.reloadReviewBlock.wrap(function(superMethod){
var name = 'checkout:reload_review_block';
$(document).fire(name + '_before', this);
var r = superMethod();
$(document).fire(name + '_after', this);
return r;
});
You could even pass the return value with the event:
var r = superMethod();
$(document).fire('eventname...', {
checkout: this,
returnValue: r
});
And you can listen to these event like so:
document.observe("checkout:reload_review_block_after", function(e) {
console.log(e.memo.returnValue);
});
This should make upgrading easier.
(Also see http://solutoire.com/2007/11/08/firing-custom-events-with-the-prototype-javascript-framework)