yusufaytas Posted June 28, 2013 Share Posted June 28, 2013 In general, compiled languages(Java, C, C++) and run-time languages(PHP, Phyton, JavaScript) have different scoping rules and execution order. I would suggest you to learn execution context for JavaScript to figure out basic understanding of how code is executed. Look at this post, http://www.yusufaytas.com/javascript-execution-context/ Link to comment Share on other sites More sharing options...
Ingolme Posted June 28, 2013 Share Posted June 28, 2013 I would disagree that experienced Javascript developers don't understand Javascript's scope and execution contexts, but this may be helpful to some of the beginners, as W3Schools doesn't make it entirely clear. Link to comment Share on other sites More sharing options...
davej Posted June 29, 2013 Share Posted June 29, 2013 The only thing I find somewhat confusing is that 'this' is often passed as a parameter but it seems to be available within the scope of an event handler function while the event object is passed as a parameter and must be received as a parameter. Link to comment Share on other sites More sharing options...
justsomeguy Posted July 1, 2013 Share Posted July 1, 2013 this always refers to the execution scope. It's an object like any other object, which means you can pass it as a parameter. But just passing this as a parameter doesn't change the value of this inside the function you pass it to. You see that with things like inline event handlers, where it passes this to the handler. In that case, for an event handler like a click event, it's passing the element that was clicked on. The reason for that is because in inline event code, this refers to the element that the event is for. So in that inline code using this is an easy generic way to pass the element that you're working with regardless of what the element actually is. But inside the actual event handler function, this doesn't refer to the element, it's running in a different scope (it's usually set to the window object, which is the default scope). That's something like this: <a onclick="alert('the scope inside this code is the element that was clicked on'); do_click(this);">test</a><script>function do_click(el){ // el is set to the element that was passed, and this is set to the window object}</script> There are a couple ways to change the scope though, to change the value of this that a particular function uses. One way is the Function.call method, and another is the Function.apply method. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply Using one of those, you can tell it what scope to execute the function under. So you can write a function which uses this and expects it to be set to something like an element, and then call that function with different scopes. e.g.: function add_child(text){ var node = document.createTextNode(text); this.appendChild(node);} // add text nodes to various elementsadd_child.call(document.getElementById('el1'), 'text for el1');add_child.call(document.getElementById('el2'), 'text for el2'); You see that a lot with jQuery code, where this typically gets set to an element that you're working on. jQuery does that by using Function.call or Function.apply to set the scope of the code you write to the elements that you're trying to work with. For example: // loop through each link and attach a click handler$('ul.nav-tabs li a').each(function() { // inside this function, this is set to each element that the previous selector matched $(this).bind('click', function() { // inside this function, this is set to the element to which the click handler is being attached // loop through each link to reset the font color $('ul.nav-tabs li a').each(function() { // inside this function, this is set to each element that the previous selector matched $(this).css('color', '#000'); }); // set the color of the selected link $(this).css('color', '#0088cc'); // get the inner HTML var html = $(this).html(); // add the checkmark icon if it's not already there if (html.indexOf('icon-ok') == -1) { $(this).html('<i class="icon-ok" style="vertical-align:middle"> </i> ' + html); } // hide all definitions $('#defHolder').children().each(function(){ // inside this function, this is set to each child of the defHolder element $(this).css('display', 'none'); }); // get the ID to show and show this definition var id_part = this.id.substr(4); // everything after "btn_" $('#' + id_part).css('display', 'block'); });}); Link to comment Share on other sites More sharing options...
davej Posted July 1, 2013 Share Posted July 1, 2013 (edited) I avoid using inline code but occasionally use something like this... <!DOCTYPE html><html><head><title>this and event</title><script>var out;window.onload = function() {document.getElementById('btn1').onclick = fn1;out = document.getElementById('out');}function fn1(e) {out.innerHTML = out.innerHTML +' '+ this.id +'@('+ e.clientX +','+ e.clientY +')';}</script></head><body><input type="button" id="btn1" value="Button"/><div id="out"></div></body></html> The scope of variables, at least in Firefox, seems to be very forgiving. In the case above even if I declare the 'out' variable inside another function the fn1 function will find it. Edited July 1, 2013 by davej Link to comment Share on other sites More sharing options...
jeffman Posted July 1, 2013 Share Posted July 1, 2013 (edited) As you are using it above, out is simply a global variable. If you use it in a function without also declaring it with the var keyword (as you do in fn1) it will retain the global context. Any changes you make to it in fn1 will affect out globally. If you use the out identifier in a function and do declare it with the var keyword, it is a whole new variable, local to that function, and global out is left alone. I would not call that forgiving. It is entirely to be expected. Edited July 1, 2013 by Deirdre's Dad Link to comment Share on other sites More sharing options...
davej Posted July 1, 2013 Share Posted July 1, 2013 I would not do this, but Firefox 21 executes the following with no errors... <!DOCTYPE html><html><head><title>this and event</title><script>window.onload = function() {init();}function init(){document.getElementById('btn1').onclick = fn1;var out = document.getElementById('out');}function fn1(e) {out.innerHTML = out.innerHTML +' '+ this.id +'@('+ e.clientX +','+ e.clientY +')';}</script></head><body><input type="button" id="btn1" value="Button1"/><div id="out"></div></body></html> Link to comment Share on other sites More sharing options...
jeffman Posted July 1, 2013 Share Posted July 1, 2013 It's not quite what you think. Try this: <!DOCTYPE html><html><head><title>this and event</title><script type="text/javascript">window.onload = function () {alert(out.innerHTML);}</script></head><body><div id="out">Hi</div></body></html> I believe that's legacy stuff, and I don't like it at all. Link to comment Share on other sites More sharing options...
davej Posted July 1, 2013 Share Posted July 1, 2013 Oh. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now