Why doesn't this work? How could I make it work (without passing a as
a variable)
What you did here is sharing the context with Function.prototype.call. Sharing the context does not share the scope variables. Scope variables aren't accessible from outside of the scope and the pig() runs in a different scope than the bear().
What you can do is
a.) sending the common variable in the arguments:
// recommended
function bear(){
var a = 1;
pig(a);
}
function pig(a){
alert(a);
}
bear();
b.) defining an object to be the common context:
// not recommended
// hard to follow where the context is coming from
function bear(){
this.a = 1;
pig.call(this);
}
function pig(){
alert(this.a);
}
var o = {};
bear.call(o);
or
// recommended
var o = {
a: undefined,
bear: function (){
this.a = 1;
this.pig();
},
pig: function pig(){
alert(this.a);
}
};
o.bear();
c.) defining a class
// not recommended
// you are defining the methods (bear and pig) by each instantiation
var My = function (){
this.bear = function (){
this.a = 1;
this.pig();
};
this.pig = function pig(){
alert(this.a);
};
};
var o = new My();
o.bear();
or
// recommended
var My = function (){};
My.prototype = {
constructor: My,
a: undefined,
bear: function (){
this.a = 1;
this.pig();
},
pig: function pig(){
alert(this.a);
}
};
var o = new My();
o.bear();
d.) defining a common variable in an upper scope
// not recommended
// (unless we are talking about a commonjs module which has its own scope)
// don't pollute the global scope with local variables
var a;
function bear(){
a = 1;
pig(a);
}
function pig(a){
alert(a);
}
bear();
or with closure
// recommended
(function (){
var a;
function bear(){
a = 1;
pig(a);
}
function pig(a){
alert(a);
}
bear();
})();