Scope rules and binding in JS.

I tend to use the following idiom quite a bit in JS:

	var obj = new Blah();

	// ...

	function Blah() {
		this.v1 = 1;
		// ...
		this.f1 = function (a, b, c) {
			return v1*(a+b+c);
		};
		// ...
	}
and it occurred to me that function() {} might not be creating references to an anonymous function, but function closures of a sort.

(I thought about this for the first time while writing the JS-prolog parsing engine)

The experiments on this page show that JS does, indeed, use lexically- scoped closures. Together with property lists, this is one of the reasons I recommend it as a serious alternative to Scheme for AI hacking and general-purpose programming.


	var y=10;
	function x() {
		var y=20;
		bleat();
	}
	function bleat() {
		print (y);
	}

This will say "10" for static scoping, "20" for dynamic.


	var z=1;
	var t;
	function p() {
		var z=2;
		t=new Ouch(3);
		print t.argh();
	}
	function Ouch(z) {
		this.argh = function() {
			return z;
		}
	}
	p();
	print t.argh();

Closures or lambda functions? "3" in both cases for closures.


	var a=1;
	var b;
	function q() {
		var a=2;
		b=new Zike(3);
		print b.argh();
		b.zow(4);
		print b.argh();
		print a;
	}
	function Zike(a) {
		this.argh = function() {
			return a;
		}
		this.zow = function(c) {
			a = c;
		}
	}
	p();
	print b.argh();
	b.zow(5);
	print b.argh();
	print a;
b.argh() =
b.zow(4);
b.argh() =
a =
(Outer) b.argh() =
b.zow(5);
(Outer) b.argh() =
(Outer) a =

If the values of a in the various scopes are unaffected by calls to zow(), then function() {} is returning closures.


	var c=1;
	var d;
	function r() {
		var c=2;
		d=new Ploop();
		print d.argh();
		d.zow(4);
		print d.argh();
		print c;
	}
	function Ploop() {
		this.argh = function() {
			return c;
		}
		this.zow = function(u) {
			c = u;
		}
	}
	r();
	print d.argh();
	d.zow(5);
	print d.argh();
	print c;
d.argh() =
d.zow(4);
d.argh() =
c =
(Outer) d.argh() =
d.zow(5);
(Outer) d.argh() =
(Outer) c =

Notice how the 'closures' are lexical in scope. More likely, they're constructed environments (using property lists) that are reference counted.