The practical difference is that delegate (and three-argument on) can cause listeners to apply to elements that don't exist yet.
$( "table td" ).on( "click", ...) attaches a listener to every element that matches the table td selector that exists at the time the call is made. If a td is added to the page after this call, it won't have a listener attached to it.
$( "table" ).delegate( "td", "click", ...) attaches a listener to every table that exists at the time the call is made, and that listener only fires when a td sub-element of that table element is clicked.
$("button").click(function() {
$("tr").append("<td>I am added after page-load time and am not targeted by load-time scripts. The listener that fires an alert does not apply to me, because I didn't exist when the <code>$('table td').click</code> code ran. However, the delegated listener still aplies, so I will turn red when you click me.</td>");
})
$("table td").on("click", function() { alert("hi"); });
$("table").delegate("td", "click", function() { $(this).css("color", "red"); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="width:70%";>
<tr>
<td>I am targeted by non-delegated event listeners set at page-load time. Click this text to trun this text red and see an alert.</td>
</tr>
</table>
<button>Add another td</button>
Delegation works because when you click a child element (like a td) you've actually clicked all of its parents (like a table and the body) as well. (To compare to human person: you can't poke a person's arm without also poking that person as a whole.) When a click listener fires for a parent, the event has a target property that indicates what element was the original target of the event.
document.getElementById("theDiv").addEventListener("click", function(e) {
if(e.target != this) {
e.target.style.color = "red";
}
});
<div id="theDiv">
<span>I'm a span, inside of a div</span><br/>
<span>I'm another span, inside of a div</span><br/>
<span>I'm a third span, inside of a div</span>
</div>
Note in this example, we add only one listener on the <div>. When we click a <span>, the click event also applies to the parent <div>. We use event.target to allow the <div> listener to find out which of its children was clicked.