JavaScript中如何调整求值策略以优化性能和效率?

2026-04-05 07:451阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1147个文字,预计阅读时间需要5分钟。

JavaScript中如何调整求值策略以优化性能和效率?

目录- 一、伪原创- 二、参数传递- 三、按值传递- 四、按引用传递- 五、总结- 六、扩展- 七、惰性求值- 八、最近研究- 九、lambda演算- 十、中的γ-变换- 十一、在JavaScript中的应用- 十二、在stackoverflow上的应用

目录
  • 一栗以蔽之
  • 参数传递
    • 按值传递
    • 按共享传递
  • 总结
    • 延伸 - 惰性求值

      最近在研究 lambda演算 中的 η-变换 在JavaScript中的应用,偶然在 stackoverflow 上看到一个比较有意思的问题。关于JavaScript的求值策略,问js中函数的参数传递是按值传递还是按引用传递?回答很经典。

      一栗以蔽之

      function changeStuff(a, b, c) { a = a * 10; b.item = "changed"; c = {item: "changed"}; } var num = 10; var obj1 = {item: "unchanged"}; var obj2 = {item: "unchanged"}; changeStuff(num, obj1, obj2); console.log(num); // 10 console.log(obj1.item); // changed console.log(obj2.item); // unchanged

      如果说js中函数的参数传递是按值传递,那么在函数changeStuff内部改变b.item的值将不会影响外部的obj1对象的值。

      如果说JS中函数的参数传递是按引入传递,那函数changeStuff内部所做的改变将会影响到函数外部所有的变量定义,num将会变成100、obj2.item将会变成changed。很显然实际不是这样子的。

      所以不能说JS中函数的参数传递严格按值传递或按引入传递。总的来说函数的参数都是按值传递的。JS中还采用一种参数传递策略,叫按共享传递。这要取决于参数的类型。

      如果参数是基本类型,那么是按值传递的;

      如果参数是引用类型,那么是按共享传递的。

      参数传递

      ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。-- 《JavaScript高级程序设计》

      红宝书上讲所有函数的参数都是按值传递的,到底是不是呢?让我们分析下上面的栗子:

      按值传递

      JavaScript中基本类型作为参数的策略为按值传递(call by value):

      function foo(a) { a = a * 10; } var num = 10; foo(num); console.log(num); // 10 没有变化

      这里看到函数内部参数的改变并没有影响到外部变量。按值传递没错。

      按共享传递

      JavaScript中对象作为参数传递的策略为按共享传递(call by sharing):

      修改参数的属性将会影响到外部对象

      重新赋值将不会影响到外部对象

      按上面栗子函数内部修改了参数b的属性item,会影响到函数外部对象,因而obj1的属性item也变了。

      function bar(b) { b.item = "changed"; console.log(b === obj1) // true } var obj1 = {item: "unchanged"}; bar(obj1); console.log(obj1.item); // changed 修改参数的属性将会影响到外部对象

      从b === obj1打印结果为true可以看出,函数内部修改了参数的属性并没有影响到参数的引用。b和obj1共享一个对象地址,所以修改参数的属性将会影响到外部对象。

      而将参数c重新赋值一个新对象,将不会影响到外部对象。

      function baz(c) { c = {item: "changed"}; console.log(c === obj2) // false } var obj2 = {item: "unchanged"}; baz(obj2); console.log(obj2.item); // unchanged 重新赋值将不会影响到外部对象

      将参数c重新赋值一个新对象,那么c就绑定到了一个新的对象地址,c === obj2打印结果为false,判断他们不再共享同一个对象地址。它们各自有独立的对象地址。所以重新赋值将不会影响到外部对象。

      总结

      可以说按共享传递是按值传递的特例,传递的是引用地址的拷贝。所以红宝书上说的也没错。

      可以把 ECMAScript 函数的参数想象成局部变量。-- 《JavaScript高级程序设计》

      延伸 - 惰性求值

      前面了解到了所有函数的参数都是按值传递的。JavaScript 中参数是必须先求值再作为实参传入函数的。但是在ES6中有一个特例。

      参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。 -- 《ECMAScript 6 入门》

      let x = 99; function foo(p = x + 1) { console.log(p); } foo() // 100 x = 100; foo() // 101

      上面代码中,参数p的默认值是x + 1。这时,每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100

      以上就是详细讨论JavaScript中的求值策略的详细内容,更多关于JavaScript求值策略的资料请关注自由互联其它相关文章!

      JavaScript中如何调整求值策略以优化性能和效率?

      本文共计1147个文字,预计阅读时间需要5分钟。

      JavaScript中如何调整求值策略以优化性能和效率?

      目录- 一、伪原创- 二、参数传递- 三、按值传递- 四、按引用传递- 五、总结- 六、扩展- 七、惰性求值- 八、最近研究- 九、lambda演算- 十、中的γ-变换- 十一、在JavaScript中的应用- 十二、在stackoverflow上的应用

      目录
      • 一栗以蔽之
      • 参数传递
        • 按值传递
        • 按共享传递
      • 总结
        • 延伸 - 惰性求值

          最近在研究 lambda演算 中的 η-变换 在JavaScript中的应用,偶然在 stackoverflow 上看到一个比较有意思的问题。关于JavaScript的求值策略,问js中函数的参数传递是按值传递还是按引用传递?回答很经典。

          一栗以蔽之

          function changeStuff(a, b, c) { a = a * 10; b.item = "changed"; c = {item: "changed"}; } var num = 10; var obj1 = {item: "unchanged"}; var obj2 = {item: "unchanged"}; changeStuff(num, obj1, obj2); console.log(num); // 10 console.log(obj1.item); // changed console.log(obj2.item); // unchanged

          如果说js中函数的参数传递是按值传递,那么在函数changeStuff内部改变b.item的值将不会影响外部的obj1对象的值。

          如果说JS中函数的参数传递是按引入传递,那函数changeStuff内部所做的改变将会影响到函数外部所有的变量定义,num将会变成100、obj2.item将会变成changed。很显然实际不是这样子的。

          所以不能说JS中函数的参数传递严格按值传递或按引入传递。总的来说函数的参数都是按值传递的。JS中还采用一种参数传递策略,叫按共享传递。这要取决于参数的类型。

          如果参数是基本类型,那么是按值传递的;

          如果参数是引用类型,那么是按共享传递的。

          参数传递

          ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。-- 《JavaScript高级程序设计》

          红宝书上讲所有函数的参数都是按值传递的,到底是不是呢?让我们分析下上面的栗子:

          按值传递

          JavaScript中基本类型作为参数的策略为按值传递(call by value):

          function foo(a) { a = a * 10; } var num = 10; foo(num); console.log(num); // 10 没有变化

          这里看到函数内部参数的改变并没有影响到外部变量。按值传递没错。

          按共享传递

          JavaScript中对象作为参数传递的策略为按共享传递(call by sharing):

          修改参数的属性将会影响到外部对象

          重新赋值将不会影响到外部对象

          按上面栗子函数内部修改了参数b的属性item,会影响到函数外部对象,因而obj1的属性item也变了。

          function bar(b) { b.item = "changed"; console.log(b === obj1) // true } var obj1 = {item: "unchanged"}; bar(obj1); console.log(obj1.item); // changed 修改参数的属性将会影响到外部对象

          从b === obj1打印结果为true可以看出,函数内部修改了参数的属性并没有影响到参数的引用。b和obj1共享一个对象地址,所以修改参数的属性将会影响到外部对象。

          而将参数c重新赋值一个新对象,将不会影响到外部对象。

          function baz(c) { c = {item: "changed"}; console.log(c === obj2) // false } var obj2 = {item: "unchanged"}; baz(obj2); console.log(obj2.item); // unchanged 重新赋值将不会影响到外部对象

          将参数c重新赋值一个新对象,那么c就绑定到了一个新的对象地址,c === obj2打印结果为false,判断他们不再共享同一个对象地址。它们各自有独立的对象地址。所以重新赋值将不会影响到外部对象。

          总结

          可以说按共享传递是按值传递的特例,传递的是引用地址的拷贝。所以红宝书上说的也没错。

          可以把 ECMAScript 函数的参数想象成局部变量。-- 《JavaScript高级程序设计》

          延伸 - 惰性求值

          前面了解到了所有函数的参数都是按值传递的。JavaScript 中参数是必须先求值再作为实参传入函数的。但是在ES6中有一个特例。

          参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。 -- 《ECMAScript 6 入门》

          let x = 99; function foo(p = x + 1) { console.log(p); } foo() // 100 x = 100; foo() // 101

          上面代码中,参数p的默认值是x + 1。这时,每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100

          以上就是详细讨论JavaScript中的求值策略的详细内容,更多关于JavaScript求值策略的资料请关注自由互联其它相关文章!

          JavaScript中如何调整求值策略以优化性能和效率?