Wednesday 15 January 2014

Javascript strage scope behaviour -



Javascript strage scope behaviour -

name = 'window data'; document.name = 'current document data'; (function(window, document) { var name = 'local data'; var myobj = { name: 'object data', f: function() { alert(this.name); } }; myobj.newfun = function() { alert("local scope " + name + "\nobject scope : " + this.name); } function testfun() { alert("window scope : " + window.name + "\nlocal scope : " + name + "\nobject scope : " + this.name + "\ncurrent document scope : " + document.name ); } myobj.newfun(); //testfun(); // promts see "object scope : window data", suppose "object scope : local data" // did not found reply testfun.call(myobj); testfun.bind({ name: "name injected" })(); })(window, document);

i found unusual behavior when tried phone call testfun() within self executing anonymous block. have added comment beside code whats happening , expected.

can explain me why happening?

the context of testfun window, behavior normal (invoking testfun() run in context of window). line have below, testfun.call(myobj) result in desired behavior (call calls function using first argument context, or this).

keep in mind you're in self executing anonymous block (or immediate function)'s closure, isn't same context. context function not bound method object window, regardless of it's closure. it's closure however, wherever function declared, if homecoming function @ end of immediate 1 , assign variable outside, alert(name) show local data , not window data, since testfun declared in closure name equals local data.

to farther clarify:

// global closure scope, context (this) window name = 'window data'; document.name = 'current document data'; var testfun = (function(window, document) { // immediate closure scope, context still window var name = 'local data'; var myobj = { name: 'object data', f: function() { // myobj.f closure scope. immediate closure scope available , superseeds global closure scope. context myobj alert(this.name); // 'object data' } }; myobj.newfun = function() { // newfun closure scope. immediate scope available , superseeds global scope. context myobj alert("local scope " + name + "\nobject scope : " + this.name); // outputs 'local data' (from immediate closure scope) , 'object data' (from myobj.name) } function testfun() { // testfun closure scope. immediate scope available , superseeds global scope. context window alert("window scope : " + window.name + // 'window data' "\nlocal scope : " + name + // 'local info (from immediate scope) "\nobject scope : " + this.name + // 'window data' (remember === window) "\ncurrent document scope : " + document.name // 'current document data' ); } myobj.newfun(); //testfun(); // promts see "object scope : window data", suppose "object scope : local data" // did not found reply testfun.call(myobj); // context testfun changed myobj **for phone call only**, this.name === 'object data' testfun.bind({ name: "name injected" })(); // context newly created object **for phone call only**, this.name === 'name injected' homecoming testfun; })(window, document); testfun(); // output same if called within immediate function, because immediate scope survives immediate function's execution , available testfun (and superseeds global scope) alert(name); // 'window data' (global scope still valid , available statements declared outside immediate scope)

javascript scope bind

No comments:

Post a Comment