zoukankan      html  css  js  c++  java
  • 也谈下javascript中的 with

    我们知道javascript是通过语句来构造代码的组织结构的,这种组织结构的基本形式是“代码分块”,而代码分块带来的语法效果,是信息隐藏。

    一般来说,所谓信息隐藏指的是变量或者成员的可见性问题,而这个可见性的区间,则依赖语法的称述,这被称作作用域,这是对作用域的一种通俗描述,作用域包括语法作用域和变量作用域两个部分,这两个部分是一个语言中,模块化层次的全部体现。

     

    javascript中的语法作用域有四种,大部分被严格限制在“语句/批语句”作用域内,with就在其中。

     

    其实如果代码可读性好的代码,with是个非常有用的语句,但是目前很多网上文章包括 犀牛书,都不推荐使用with,这是为什么。

     

    至少我是经常用到with在一些特定的场合,需要临时而短暂的切换作用域干活,比如临时切换到一个window.a.b.c.d.obj的对象来给这个obj进行一个属性的深度复制。

     

    如果一定要说with的问题,那么我想并不是with会带来性能上的缺陷,with语句并不可怕,它有它存在理由。

    那么我们抛开性能上的思路来看这么一种情况。

    在 with 语句内部通过内部变量修改数值

    var person = {
    
        man : {
            name: "nick"
        }
    };
     
    with(person.man ) {
        name = "baby";
        // 显示 baby , 正确!
        alert(name);
    }
    // 显示 baby, 正确!
    alert(person.man.name);

    but

    var person = {
    
        man : {
            name: "nick"
        }
    };
     
    with(person.man ) {
        person.man = {
            name : "baby"
        }
        // 显示 nick , why!
        alert(name);
    }
    // 显示 baby, 正确!
    alert(person.man.name);


    这里一看上去 确实 有点 绕,why? with语句的作用就是把作用域切换为操作对象,with的{} 语句块 会 进入到切换后的作用域,然后等语句块执行完在切换回原来的作用域(也有说法是这样作用域的切换带来的性能消耗?这个.......)

    --------------------------------------------------------------华丽的解释线--------------------------------------------

    进入with语句块的时候,js会创建一个临时的with对象,暂且称之为withobj:withobj的parent为当前的scope chain,withobj的__proto__为with语句块的参数root.branch。

    with(person.man) {
    person.man = {
    name: "baby"
    };
    // 显示 "nick", 和预想的不一样! bug!!!!!!!!!!
    alert(name);
    }
    with语句块中将person.man修改成另外一个对象,此时withobj的__proto__还是原来的对象{name:"nick"}.于是便出现了例子二的"bug".

    所以with语句并没有bug,而是一个正常的语法现象。

    犀牛书里也是不推荐使用with语句但是并没有提过with会带来低效,同时也简单的说了这么两点
    一是代码难优化, 同比不用with的代码低
    二就是我上面说的这个问题了, with语句作用域内外对象的迷魂阵

  • 相关阅读:
    搭建strom 的开发环境
    maven 的plugin 的使用
    Maven 的dependency 的 classifier的作用
    Maven中的dependency的scope作用域详解
    Supervisor-进程监控自动重启
    websocket 实战
    vue 监听路由变化
    vux-uploader 图片上传组件
    vue 定义全局函数
    判断对象属性的值是否空,如为空,删除该属性
  • 原文地址:https://www.cnblogs.com/litao229/p/2514978.html
Copyright © 2011-2022 走看看