Imagine this scenario: You want to create a simple user control that you can use in a few web pages. It incorporates a few JavaScript functions that change the UI slightly during a mouse click; pretty standard stuff. The script isn't particularly useful in other controls, so putting it into a common library doesn't make much sense. It could be broken out into it's own library, which can at least be cached by a browser. But that introduces another dependency in the hosting page - you have to remember to include a reference to this JS library before things will work. The easiest thing to do would be to just include the JS code inside the user control itself (I'm skipping the option of embedding it as a resource; maybe another day). Including the code in the control is pretty simple and seamless. Until you drop two instances of the same control on page. What you'll find (like I did) is that your JS code is now rendered one time for each control. That's not very cool. In fact, you run into this same issue even if you decide to move the code into it's own library - you end up with more than one reference to the library.
A relatively simple way around all this is the ClientScriptManager class that is available hanging off the Page object as ClientScript. It lets you register JS code to be rendered into the main page. You can also check for the existence of the registered code (to keep from registering it more than once, regardless of the number of controls on the page). In my case, since I'm just embedding the code right in the page, there are only two methods required for this: IsClientScriptBlockRegistered and RegisterClientScriptBlock.
The routines use the object type and the passed in name as a key; if you don't pass it into IsClientScriptBlockRegistered (or the other variants) the routines will use the Page's type. I'd suggest always passing in something besides the page type (for example, the user control type). This will keep you from running into conflicts if you happen to use the same registration name (although things will still break if you picked the same JS function names).
Here's what that might look like:
if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(WebmailAddressBookBizObj), "ToggleCheck"))
{
string js = @"
function ToggleCheck(node)
if (node.Checked)
node.UnCheck();
else
node.Check();
}";
Page.ClientScript.RegisterClientScriptBlock(typeof(WebmailAddressBookBizObj), "ToggleCheck", js, true);
}