• with语句


    with语句的格式如下:

    with (object) {
      statements;
    }
    

    它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

    // 例一
    with (o) {
      p1 = 1;
      p2 = 2;
    }
    // 等同于
    o.p1 = 1;
    o.p2 = 2;
    
    // 例二
    with (document.links[0]){
      console.log(href);
      console.log(title);
      console.log(style);
    }
    // 等同于
    console.log(document.links[0].href);
    console.log(document.links[0].title);
    console.log(document.links[0].style);
    

    注意,with区块内部的变量,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。这是因为with区块没有改变作用域,它的内部依然是当前作用域。

    var o = {};
    
    with (o) {
      x = "abc";
    }
    
    o.x // undefined
    x // "abc"
    

    上面代码中,对象o没有属性x,所以with区块内部对x的操作,等于创造了一个全局变量x。正确的写法应该是,先定义对象o的属性x,然后在with区块内操作它。

    var o = {};
    o.x = 1;
    
    with (o) {
      x = 2;
    }
    
    o.x // 2
    

    这是with语句的一个很大的弊病,就是绑定对象不明确。

    with (o) {
      console.log(x);
    }
    

    单纯从上面的代码块,根本无法判断x到底是全局变量,还是o对象的一个属性。这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,只能留到运行时判断,这就拖慢了运行速度。因此,建议不要使用with语句,可以考虑用一个临时变量代替with

    with(o1.o2.o3) {
      console.log(p1 + p2);
    }
    
    // 可以写成
    
    var temp = o1.o2.o3;
    console.log(temp.p1 + temp.p2);
    

    with语句少数有用场合之一,就是替换模板变量。

    var str = 'Hello <%= name %>!';
    

    上面代码是一个模板字符串。假定有一个parser函数,可以将这个字符串解析成下面的样子。

    parser(str)
    // '"Hello ", name, "!"'
    

    那么,就可以利用with语句,进行模板变量替换。

    var str = 'Hello <%= name %>!';
    
    var o = {
      name: 'Alice'
    };
    
    function tmpl(str, obj) {
      str = 'var p = [];' +
        'with (obj) {p.push(' + parser(str) + ')};' +
        'return p;'
      var r = (new Function('obj', str))(obj);
      return r.join('');
    }
    
    tmpl(str, o)
    // "Hello Alice!"
    

    上面代码的核心逻辑是下面的部分。

    var o = {
      name: 'Alice'
    };
    
    var p = [];
    
    with (o) {
      p.push('Hello ', name, '!');
    };
    
    p.join('') // "Hello Alice!"
    

    上面代码中,with区块内部,模板变量name可以被对象o的属性替换,而p依然是全局变量。这就是很多模板引擎的实现原理。

  • 相关阅读:
    linux的redis的安装和使用
    在linux上安装Mysql和使用
    linux的python3的安装
    linux的优化和命令
    LeetCode 542. 01 Matrix
    Qt keyPressEvent
    QOpenGLTexture 两个纹理叠加
    Qt5.6.0+OpenGL 纹理贴图首战告捷
    更改Qt Application为 Qt Console Application
    Learning part-based templates from large collections of 3D shapse CorrsTmplt Kim 代码调试
  • 原文地址:https://www.cnblogs.com/youcandoit-/p/7903302.html
Copyright © 2020-2023  润新知