深究js(九)——语句的其他类型(语句Ⅳ)

来源:互联网 发布:js的某个div全屏显示 编辑:程序博客网 时间:2024/06/05 11:04

        语句还有另外三个比较常见的,一个是with语句、一个是debugger语句、还有一个声明严格模式的use strict语句。

一、with语句

        with语句主要是用于临时扩展作用域链,它的语法如下:

with (object)statement
        这条语句是将object添加到作用域链的头部,然后执行statement,最后把作用域链恢复到原始状态。with语句通常用在客户端JavaScript中,用在减少代码的量,如下面的w例子;

with(document.forms[0]){name.value = '';address.value = '';email.value = '';}
        等价于:

document.forms[0].name.value = '';document.forms[0].address.value = '';document.forms[0].email.value = '';
        也可以这样写:
var a = document.forms[0];a.name.value = '';a.address.value = '';a.email.value = '';

        如果对象中没有某个属性而with语句中却有这个属性的声明,则这个属性升级为全局变量。如:

with(o){x=1}var o = {}
        这里的x属性会升级为全局变量。with语句在严格模式中是不能使用的,因为with语句它有些缺陷,比如说它运行的比较慢和难以调试。下面举一个例子说明它的运行慢:

function a() {console.time("a");var obj = []for (var i = 0; i < 100000; i++) {obj[i] = i}console.timeEnd("a");}a();function b() {console.time("a");var a = []with (a) {for (var i = 0; i < 100000; i++) {    a[i] = i}}console.timeEnd("a");}b();
        在第一个结果中,浏览器返回的结果是7.95ms,但是在第二个结果,即使你的计算机再快,也会消耗比较多的时间,在我的浏览器里显示的是132.84ms,所以使用with语句对性能有一定的影响。这是因为JavaScript引擎无法优化with内的代码,也就是说,用with的效率非常的低。长此以往,它还有一个致命的漏洞,那就是语意不明,难以调试。首先先看这段代码:

function foo(obj) {with (obj) {    a = 2;}} var o1 = {a: 3};var o2 = {b: 3}; foo(o1);console.log(o1.a);  foo(o2);console.log( o2.a ); console.log( a ); 
        在这段代码中,对象o1进入foo()函数内,在那里a被重新赋值为2。而在o2对象里,由于在with中找不到属性b,所以属性b成为一个全局变量,这就给程序带来了很大的不确定因素。下面的例子将更加详细的分析with语句。

var obj = {x: 10,foo: function () {    var x;    var y;    with (this) {      x = 20;      y = 30;      console.log(y);    }}};obj.foo();console.log(obj.x);console.log(obj.y);
        在这个例子中有this和with,首先我们先要搞清楚this指的是谁。this指的是调用该函数的对象,由此可见,这里的this指的是obj。在foo()函数里,有局部变量x和y, 在with语句中给x赋值,实际上就是对obj对象的x属性重新赋值。由于obj对象里没有y属性,所以这里的y变量会成为全局变量,所以返回的结果是赋值后的结果30,但是obj里没有y属性,所以obj.y的结果是underfined。而obj.x的结果是20。一般来说,由于with语句有很多弊端,最好不要随便用,但是理解好with语句对理解JavaScript的原型链和作用域链有很大的帮助。


二、debugger语句

        debugger语句通常什么也不做,只有当调试程序可用并运行的时候,JavaScript将会以调试模式运行。这样这条语句就会产生一个断点,JavaScript的代码执行就会在断点处停止,这时可用使用调速器输出变量的值检查调用的栈。如下面的就是没有定义参数o,用debugger检测:

function f(o) {        if(o === underfined) debugger}
        这时会返回出错的原因。


三、use strict

        "use strict"是ECMAScript5引入的一条指令。指令与语句有两个比较重要的区别。一是指令不包含任何语言的关键字,指令仅仅是一个包含一个特殊字符串直接量的表达式。在ECMAScript之前的版本中,即使使用这一句也不会报错。二是它只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。但不一定在脚本首行或者函数体内首行,只要在想要执行严格模式的代码之前就可以。严格模式它修正了语言的重要缺陷,并提供健壮的查错功能和增强安全机制。下面是严格模式和非严格模式的区别,摘自《JavaScript权威指南》:





四、语句语法表

        这个表摘自《JavaScript权威指南》,请看图:




阅读全文
0 0
原创粉丝点击