The with() {} statement is meant to provide convenience.
and there are some golden laws about the with() {} statement.
- it only use/assign existing properties
- it does not affect what is 'this'
- the scoped variable inside with statement take precedence over others with the same name
- it slows things down.,
let's first see some simple example that shows something about the with statement.
/************************************** *@Summary * this shows the simple use of with statement * * the key rule about the use of the statement is that it * 1. does not affect what is 'this' context. * 2. it does not help create properties that is not in the 'with' scoped variable. You can only use and assign existing properties in the with() {} statement * 3. within the scope of the statement, the properties introduced by with(){} take precedence over the other variables. * 4. and it slows things down (not sure where comes the extra overhead) * @Usage: * * @TODO: * test it ***************************************/ var use = "other"; var katana = { isSharp: true, use: function () { this.isSharp = !this.isSharp; } }; //with (katana) { // assert(true, "you can still call outside mehtods."); // isSharp = false; // use(); // // this illustrate the fact that local with variable take precedence // assert(use !== "other", "Use is a function, from the kantana object"); // assert(this !== katana, "This isn't changed - it keeps its original value"); //} // commentted out, to test it , copy the following code to the test html and do the test //assert(typeof isSharp === "undefined", "Outside the with, the properties don't exist."); //assert(katana.isSharp, "Verify that the method was used correctly in the with.");
and below is its test cases.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="../unit.js" type="text/javascript"></script>
<script src="simplewith.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function () {
test("with(){} doest not change what 'this' is. and it simplifies things", function () {
with (katana) {
assert(true, "you can still call outside mehtods.");
isSharp = false;
use();
// this illustrate the fact that local with variable take precedence
assert(use !== "other", "Use is a function, from the kantana object");
assert(this !== katana, "This isn't changed - it keeps its original value");
}
assert(typeof issharp === "undefined", "outside the with, the properties don't exist.");
assert(katana.isSharp, "verify that the method was used correctly in the with.");
});
test("you cannot access non-existing properties inside with(){} statement", function () {
with (katana) {
isSharp = false;
cut = function () {
isSharp = false;
};
}
assert(!katana.cut, "The new cut property wasn't introduced here.");
assert(this.cut, "It was made as a member variable to the anonymous function that contains the test instead.");
});
};
</script>
<style type="text/css">
#results li.pass {color: Green}
#results li.fail { color: Red}
</style>
</head>
<body>
<ul id="results"
</body>
</html>
also, with the 'with' statement, you can chang the way how the code is written to simulate some object-oriented javascript code.
/************************************** *@Summary * this shows how you can use the with statement to facilitate writting some OO like code. * * the key rule about why the use of the statement has the advantage is that * 1.it introduce a local scope * 2. you can have something like private and public, which is missing in non-with statement * 3. you can access the private and public through names alike inside the with statement, but outside the visibility is different. * @Usage: * * @TODO: * test it ***************************************/ function Ninja(){with(this){ // Private Information var cloaked = false; // Public property this.swings = 0; // Private Method function addSwing(){ return ++swings; } // Public Methods this.swingSword = function(){ cloak( false ); return addSwing(); }; this.cloak = function (value) { return value != null ? cloaked = value : cloaked; }; } } // below is the test code. var ninja = new Ninja(); assert(!ninja.cloak(), "We start out uncloaked."); assert(ninja.swings == 0, "And with no sword swings."); assert(ninja.cloak(true), "Verify that the cloaking worked correctly."); assert(ninja.swingSword() == 1, "Swing the sword, once."); assert(!ninja.cloak(), "The ninja became uncloaked with the sword swing.");