博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript:with的用法以及延长作用域链
阅读量:5740 次
发布时间:2019-06-18

本文共 1556 字,大约阅读时间需要 5 分钟。

 

    《Javascript高级程序设计(第二版)》第66页中提到:“由于with语句的变量对象是只读的,结果url就成了函数执行环境的一部分,因而可以作为函数的值被返回。”,不知道谁看完觉得一头雾水?

 

    首先来看看他举的例子:

 

Js代码  
  1. function buildUrl(){  
  2.      var qs="?debug=true";  
  3.      with(location){  
  4.           var url=href+qs;  
  5.      }  
  6.      return url;  
  7. }  
  8. var result=buildUrl();  
  9.   
  10. alert(result);  

 

    如果你没读过着本书,并且需要学习javascript,请思考并尝试运行该例子。

 

    最后弹出的不是undefined,而是你的静态页地址+qs的值。

 

来看一下with语句的作用:

 

    通俗的说,就是引用对象,并对该对象上的属性进行操作,其作用是可以省略重复书写该对象名称,起到简化书写的作用。

 

但是有几个问题需要注意:

 

   1、with代码块中,javascript引擎对变量的处理方式是:先查找是不是该对象的属性,如果是,则停止。如果不是继续查找是不是局部变量。(在《Javascript高级程序设计(第二版)》中提到的观点,跟这一点恰好相反,但是实例可证明其是错误的,会在接下来介绍)

 

   2、就算在with语句中使用 var 运算符重新定义变量(该变量是with引用对象的属性),如果该属性是可写属性,那么也会给对象的属性赋值。

 

   3、如果你想通过with语句,对引用对象添加多个属性,并为每个属性赋值,这是不可能的!也就是说,要赋值的只能是对象已经存在并且可以写入的属性(不能是只读属性)。

 

再来看看开头提到的那句话

 

    “由于with语句的变量对象是只读的,结果url就成了函数执行环境的一部分,因而可以作为函数的值被返回。”

 

    反过来:如果with语句的变量对象是可写入的…… 刚才第3点提过,不能给对象写入原来不存在的属性,先这样理解,下面还有另外的含义。

 

那延长作用域链又是怎么回事?

 

   一般的,“由于with语句块中作用域的‘变量对象’是只读的,所以在他本层定义的标识符,不能存储到本层,而是存储到它的上一层作用域”。这里又要理解有一层“只读”的含义。

 

   在Javascript的作用域中(作用域,想想就是函数块,每个函数都会有个函数名,就算是匿名函数也有个空函数名),那么创建作用域的时候,本层的标识符就可以寄托在这个作用域下,而with语句块中作用域的‘变量对象’是只读的,不能存储标识符,只能存储在其上一层,这就是延长作用域链。其实,这和上面说的不能给对象添加属性有同工之处。

 

   其实,完全可以这样理解,在Javascript中,没有块级作用域,就是说除了函数,其他的块级代码都没有自己的作用域。

 

现在说一下之前提到的with代码块中变量处理方式的问题

 

   用事实说话:

 

Js代码  
  1. var o={href:"sssss"};  
  2. var href="1111";  
  3. function buildUrl(){  
  4.      var qs="?debug=true";       
  5.      with(o){  
  6.           href="2222";  
  7.           var url=href+qs;  
  8.      }      
  9.      return url;  
  10. }  
  11. var result=buildUrl();  
  12. alert(result);  
  13. alert(href);  

 

    结果:2222?debug=true  +  1111

 

    很明显,with语句中并没有更改变量href的值,而是更改了 o 对象的 href 属性。

 

    就是说,with中首先查找的是相关对象的属性,如果没有,才改变变量的值。你可以将以上例子o对象的href属性去掉看看。

 

转载于:https://www.cnblogs.com/zz334396884/p/4951042.html

你可能感兴趣的文章
多项式前k项和java_多项式朴素贝叶斯softmax改变
查看>>
java数组只能交换0下标和n_编程练习-只用0交换排序数组
查看>>
java的maxrow_聊聊pg jdbc statement的maxRows参数
查看>>
centos7安装mysql视频教程_centos7安装mysql(完整)
查看>>
php图片赋值,php如何优雅地赋值
查看>>
dz.27z.co index.php,dz7.2 伪静态规则
查看>>
如何解决OutOfMemoryError
查看>>
【探索HTML5第二弹01】HTML5的前世今生以及来世
查看>>
Failed to connect to remote VM. Connection refused. Connection refused: connect
查看>>
freeze
查看>>
JS时间转时间戳,时间戳转时间。时间显示模式。
查看>>
SAP HANA存储过程结果视图调用
查看>>
设计模式 ( 十八 ):State状态模式 -- 行为型
查看>>
OracleLinux安装说明
查看>>
nova分析(7)—— nova-scheduler
查看>>
hive 权限:Authorization failed:No privilege 'Create' found for outputs .
查看>>
HDU1007 Quoit Design
查看>>
Memcached安装
查看>>
MVVM中的命令绑定及命令参数
查看>>
python Gunicorn
查看>>