Rumah > hujung hadapan web > View.js > 深入浅析With的使用

深入浅析With的使用

青灯夜游
Lepaskan: 2020-10-23 17:45:58
ke hadapan
2725 orang telah melayarinya

深入浅析With的使用

with用于扩展一个语句的作用域链,但一般情况下不建议使用with语句,因为它可能是引起混淆错误和兼容性问题的根源。在Vue源码中有使用with语句的功能点,因此在这里将简介其功能,以助于阅读框架源码。

性能的利与弊

with语句可以在不造成性能损失的情況下,减少变量的长度。其造成的附加计算量很少。使用'with'可以减少不必要的指针路径解析运算。但是在大部分情况下,即使不使用with,使用临时变量来保存指针或者使用call,也能达到同样的效果。

with语句使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来将会很慢。

示例

let obj = {
    a: 1,
    b: 2,
    c: 3
}
with(obj){
    console.log(a)    //1
    console.log(b)    //2
    console.log(c)    //3
}
Salin selepas log masuk

这段代码中,with关联的obj对象,在with代码块中,每个变量都首选被认为是一个局部变量,如果这个局部变量与obj对象的某个属性同名,则这个局部变量会指向obj对象属性。

function fn(obj){
    with(obj){
        a = 1;
    }
}
let obj1 = {
    a: 2
}
let obj2 = {
    b: 3
}

fn(obj1);
console.log(obj1.a)     //1

fn(obj2)
console.log(obj2.a)     //undefined
console.log(a)          //1,变量a被泄漏到全局作用域链上
Salin selepas log masuk

上例中,obj1存在a属性,obj2没有a属性。fn(obj)接收一个obj形参,是一个对象引用,并执行了with(obj)。在with代码块的内部,对a实际上是一个引用,将1赋值给了a。

当传递obj2给with时,with所声明的作用域就是obj2,从这个作用域下开始对a进行查询。obj2的作用域、fn的作用域和全局作用域中都没有查找到标识符a,因此在非严格模式下会自动在全局作用域创建一个全局变量,而严格模式下则会抛出ReferenceError错误。

性能降低

如果在代码中使用了with,那么JS引擎在编译阶段只能简单地假设关于标识符的判断都将无效,因为编译器也不能知道传递给with的作用域对象到底是谁。因此JS引擎在编译阶段进行的性能优化都将无效。最糟糕的情况,那就是如果出现了with,所有的优化都将变得无意义。最简单的做法就是不做任何优化,那么运行起来一定会很慢,这将是无法避免的事实。

Vue中的with

Vue 在 compile 的时候,会把 template 生成对应的 render function,而这个 render function中又正好使用了with语句。按照上文来说,不建议使用with语句,为什么在Vue中又会使用到呢?

相关推荐:《vue.js教程

function render () {
  with (this) {
    return _c('p',{on:{"click":change}},[_c('span',[_v(_s(number))]),_v(" "),_c('span',     [_v(_s(name))])])
  }
}
Salin selepas log masuk

因为with 的作用域和模板的作用域正好契合,可以极大地简化模板编译过程。而with的代码量很少,把作用域的处理交给JS引擎来做也更可靠。当然,最理想的情况还是要去掉with的使用,预编译的时候会自动把第一遍编译生成的代码进行一次额外处理,用完整的AST分析来处理作用域,把with拿掉,顺便支持ES6语法。换句话说,如果用 webpack + vue 的时候,最终生成的代码是没有 with 的。

相关推荐:

2020年前端vue面试题大汇总(附答案)

vue教程推荐:2020最新的5个vue.js视频教程精选

更多编程相关知识,请访问:编程入门!!

Atas ialah kandungan terperinci 深入浅析With的使用. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan