secrets of the javascript Ninja( with(){} 的用法)(javascript忍者的秘密)
2009-03-25 22:26
507 查看
with语句也是一个功能强大的特性,但是它常常不能被正确的理解。它允许你把一个对象的所有属性放到with语句所指定的作用域中,这样这些属性就可以想平常的JavaScript变量被使用。理解with语句是如何工作的,在你开发中会带来很大的好处。
从这个例子我们来总结一下with的基本用法:
1.在with(){}语句中,你可以直接使用with指定的对象的变量和方法。
2.如果外部存在和with指定的对象的变量同名的属性,那么with指定对象中的属性会覆盖其他同名的属性。
3.this指定的是katana的外部作用域。
那么我们能否在with(){}语句中添加一些属性和方法呢?来看一段代码:
从上面的代码我们可以发现:
1.在with语句中只能使用和更改对象已有属性,不能为对象添加新的属性
2.如果为对象添加新的属性,新添加的属性会作为全局对象的属性,而不是with指定对象的属性。
Prototype库中使用with(){}的情况。
下面是base2库中使用with的情况:
base2中另外的一中情况:
Firebug firefox extension中使用with(){}的情况
导入命名空间的时候使用如下
第二个代码是不是简单了很多。
净化面向对象的代码,使用如下方式编写面向对象的代码。
从上面的代码我们可以发现一下三点:
1.私有数据和共有数据是的定义是不一样的
2.由于使用with(this){}使得访问共有数据和私有数据是一样的
3.方法的的定义和变量的定义相似,共有方法必须使用this前缀,但是访问共有方法的时候和私有方法是一样的,由于使用with(this){}
测试
下面是Scriptaculous test suite.中的一个示例
模板
下面来看看John Resig写的一个模板系统:
具体解释在此:http://ejohn.org/blog/javascript-micro-templating/
JavaScript中with(){}语句是如何工作的
让我们首先通过一个小例子来看看with(){}语句的基本用法:var use = "other"; var katana = { isSharp: true, use: function(){ this.isSharp = !!this.isSharp; } }; with ( katana ) { //assert( true, "You can still call outside methods." ); isSharp = false; use(); alert(use!='other');//true alert(this);//window Object //assert( use != "other", "Use is a function, from the katana object." ); //assert( this != katana, "this isn't changed - it keeps its original value" ); } alert(typeof isSharp);//undefined alert(katana.isSharp);//false
从这个例子我们来总结一下with的基本用法:
1.在with(){}语句中,你可以直接使用with指定的对象的变量和方法。
2.如果外部存在和with指定的对象的变量同名的属性,那么with指定对象中的属性会覆盖其他同名的属性。
3.this指定的是katana的外部作用域。
那么我们能否在with(){}语句中添加一些属性和方法呢?来看一段代码:
var katana = { isSharp: true, use: function(){ this.isSharp = !!this.isSharp; } }; with ( katana ) { isSharp = false; cut = function(){ isSharp = false; }; } alert(katana.cut);//undefined alert(cut); }
从上面的代码我们可以发现:
1.在with语句中只能使用和更改对象已有属性,不能为对象添加新的属性
2.如果为对象添加新的属性,新添加的属性会作为全局对象的属性,而不是with指定对象的属性。
JavaScript中如何使用with(){}语句
我们主要通过一些著名的JavaScript库的示例代码来看看with(){}如何使用:Prototype库中使用with(){}的情况。
Object.extend(String.prototype.escapeHTML, { div: document.createElement('div'), text: document.createTextNode('') }); with (String.prototype.escapeHTML) div.appendChild(text);
下面是base2库中使用with的情况:
with (document.body.style) { backgroundRepeat = "no-repeat"; backgroundImage = "url(http://ie7-js.googlecode.com/svn/trunk/lib/blank.gif)"; backgroundAttachment = "fixed"; }
base2中另外的一中情况:
with (document.body.style) { backgroundRepeat = "no-repeat"; backgroundImage = "url(http://ie7-js.googlecode.com/svn/trunk/lib/blank.gif)"; backgroundAttachment = "fixed"; }
base2中另外的一中情况:
var Rect = Base.extend({
constructor: function(left, top, width, height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
this.right = left + width;
this.bottom = top + height;
},
contains: function(x, y) {
with (this) return x >= left && x <= right && y >= top && y <= bottom;
},
toString: function() {
with (this) return [left, top, width, height].join(",");
}
});
Firebug firefox extension中使用with(){}的情况
const evalScriptPre = "with (.vars) { with (.api) { with (.userVars) { with (window) { const evalScriptPost = "}}}}"; with ( obj ) { with ( window ) { ... } }
导入命名空间的时候使用如下
YAHOO.util.Event.on( [YAHOO.util.Dom.get('item'), YAHOO.util.Dom.get('otheritem')], 'click', function(){ YAHOO.util.Dom.setStyle(this,'color','#c00'); } ); with ( YAHOO.util.Dom ) { YAHOO.util.Event.on([get('item'), get('otheritem')], 'click', function(){ setStyle(this,'color','#c00'); });
第二个代码是不是简单了很多。
净化面向对象的代码,使用如下方式编写面向对象的代码。
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; }; }}
从上面的代码我们可以发现一下三点:
1.私有数据和共有数据是的定义是不一样的
2.由于使用with(this){}使得访问共有数据和私有数据是一样的
3.方法的的定义和变量的定义相似,共有方法必须使用this前缀,但是访问共有方法的时候和私有方法是一样的,由于使用with(this){}
测试
下面是Scriptaculous test suite.中的一个示例
new Test.Unit.Runner({ testSliderBasics: function(){with(this){ var slider = new Control.Slider('handle1', 'track1'); assertInstanceOf(Control.Slider, slider); assertEqual('horizontal', slider.axis); assertEqual(false, slider.disabled); assertEqual(0, slider.value); slider.dispose(); }}, // ... });
模板
下面来看看John Resig写的一个模板系统:
(function(){ var cache = {}; this.tmpl = function tmpl(str, data){ // Figure out if we're getting a template, or if we need to // load the template - and be sure to cache the result. var fn = !//W/.test(str) ? cache[str] = cache[str] || tmpl(document.getElementById(str).innerHTML) : // Generate a reusable function that will serve as a template // generator (and which will be cached). new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};" + // Introduce the data as local variables using with(){} "with(obj){p.push('" + // Convert the template into pure JavaScript str .replace(/[/r/t/n]/g, "") .split("<%").join("/t") .replace(/((^|%>)[^/t]*)'/g, "$1/r") .replace(//t=(.*?)%>/g, "',$1,'") .split("/t").join("');") .split("%>").join("p.push('") .split("/r").join("//'") + "');}return p.join('');"); // Provide some basic currying to the user return data ? fn( data ) : fn; }; })(); assert( tmpl("Hello, <%= name =>!", {name: "world"}) == "Hello, world!", "Do simple variable inclusion." ); var hello = tmpl("Hello, <%= name =>!"); assert( hello({name: "world"}) == "Hello, world!", "Use a pre-compiled template." );
具体解释在此:http://ejohn.org/blog/javascript-micro-templating/
相关文章推荐
- secrets of the javascript Ninja (Function Prototypes)(javascript忍者的秘密)
- 《Secrets of the JavaScript Ninja》:JavaScript 之运行时代码
- secrets of the javascript Ninja(Function Type)(javascript忍者的秘密)
- 翻译 Secrets of the JavaScript Ninja - 2.测试和debug(2.Testing and debugging)
- secrets of the javascript Ninja( javascript Timer)(javascript忍者的秘密)
- 翻译《Secrets of the JavaScript Ninja》—— 第一章 介绍
- 翻译 Secrets of the JavaScript Ninja - 4.挥舞函数(4.Wielding functions)
- [在读]Secrets of the javascript Ninja
- 翻译 Secrets of the JavaScript Ninja - 5.闭包 (5.Closing in on closures)
- Secret of the JavaScript Ninja 学习笔记 - 3
- Secret of the JavaScript Ninja 学习笔记 - 5
- Secret of the JavaScript Ninja 学习笔记 - 4
- 浏览器开发调试工具的秘密 - Secrets of the Browser Developer Tools
- secret of the javascript ninja笔记
- 使用JavaScript展开/折叠TreeView中所有节点(Expand and Collapse All Nodes of asp.net Treeview on the client with javascript)
- 翻译 Secrets of the JavaScript Ninja (JavaScript忍者禁术)
- 浏览器开发调试工具的秘密 - Secrets of the Browser Developer Tools
- Secret of the JavaScript Ninja 学习笔记 - 6
- 浏览器开发调试工具的秘密 - Secrets of the Browser Developer Tools
- 浏览器开发调试工具的秘密 - Secrets of the Browser Developer...