当前位置: 首页 > 知识库问答 >
问题:

vue.js - Vue源码中关于拦截数组方法的困惑?

孙子民
2023-07-13
// Vue 2.0 src/core/observer/array.js

;[
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'sort',
    'reverse'
]
    .forEach(function (method) {
        // cache original method
        const original = arrayProto[method]
        def(arrayMethods, method, function mutator() {
            // avoid leaking arguments:
            // http://jsperf.com/closure-with-arguments(失效)
            let i = arguments.length
            const args = new Array(i)
            while (i--) {
                args[i] = arguments[i]
            }
            const result = original.apply(this, args)

注释中说避免泄露参数。不明白如果不按源码中那么写,是如何有泄露参数的风险?

共有3个答案

益阳平
2023-07-13

如果不按照这种方式处理参数,直接在内部函数中使用外部函数的参数,可能会导致以下问题:

闭包引用:如果内部函数 mutator 直接引用外部函数的参数,那么在闭包中会保留对这些参数的引用。这可能导致内存泄漏,因为这些参数的引用将被持续保留,即使它们在外部函数执行完后不再需要。

参数修改:如果内部函数 mutator 直接修改外部函数的参数,可能会导致意外的副作用。因为外部函数的参数是在外部调用时传递的,如果在内部函数中直接修改这些参数,可能会影响到外部函数的调用者。

通过将外部函数的参数复制到新的数组中,并在内部函数中使用这个新数组,可以避免闭包引用和参数修改的问题,确保代码的正确性和可维护性。
GPT回答的

常俊爽
2023-07-13

我觉得楼上乔治老哥的说法已经很详细了 补充一下我的见解:
首先这里的leaking arguments
指的其实是:传递arguments对象给任何方法的这一行为
那么这里注释里写了avoid避免,那么为什么要避免这一行为呢?
因为在vue2.0那个时候 JS引擎V8会跳过对leaking arguments的优化,这也将使性能相当慢
同时arguments对象是没有filter、map和forEach这样内建到数组内的方法的,
于是这种写法既能保证V8的优化,又能得到一个具有原型对象所有内建方法的完整数组对象,
现在的V8引擎是能够针对leaking arguments进行优化的
所以我们看到现在vue2.x的最新版本2.7.14里面这块的写法:
image.png
已经变成直接拿arguments对象直接给apply方法了

参考资料:
避免修改和传递arguments给其他方法 — 影响优化-By@berkana/github

董俊
2023-07-13

这里的内存泄露是说,防止新建没必要的arguments对象,来优化性能,旧的JS引擎里arguments对象和函数参数之间有链接。如果你改了arguments对象里的值,对应的函数参数也会变,但是现在的JS引擎对arguments对象已经做过优化了,直接用arguments对象不会影响性能,vue是为了保证所有环境的性能,所以不直接用arguments对象。

 类似资料:
  • 我正在使用AeyJ拦截一个名为的方法。为此,我使用了我自己指定的(标记)注释。这就是类的样子: 截取截取注释的方面: 然而,我的方面是基于带注释的参数进行拦截。但我希望方面能够拦截参数t包含的特定值的方法请求。 例如,如果t==“t1”,则必须截取该方法,否则不能截取。 我想知道是否可以在AeyJ(与Spring AOP结合使用)中做到这一点。

  • 问题内容: 我正在用python实现RESTful Web服务,并想通过拦截函数调用并记录其执行时间等方式来添加一些QOS记录功能。 基本上,我想到了所有其他服务都可以从中继承的类,该类会自动覆盖默认方法的实现,并将其包装在logger函数中。实现此目标的最佳方法是什么? 问题答案: 像这样吗 这暗示着在您的方法中添加装饰器(如果您愿意,也可以基于此创建一个显式装饰器): 当您现在尝试类似的方法:

  • 问题内容: 我有这个代码 有什么方法可以在没有子类化或修改类且没有工厂的情况下拦截呼叫? 编辑:抱歉忘了提到这是在Android平台上。 问题答案: 您是否考虑过面向方面的编程,甚至还考虑过AspectJ?有关AspectJ / Android的信息,请参见此处和此处。

  • 问题很简单 在这里打破头! 编辑:一个小突破。我打印了目标,它返回的是SimpleJPrepository,而不是实际的存储库。

  • 本文向大家介绍Vue 拦截器对token过期处理方法,包括了Vue 拦截器对token过期处理方法的使用技巧和注意事项,需要的朋友参考一下 最近在做的一个项目,需要每个http请求下 都要添加token,这样无疑是增加了工作量。而vue 拦截器interceptors正好可以解决我们的需求。 以上这篇Vue 拦截器对token过期处理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望

  • 本文向大家介绍vue axios请求拦截实例代码,包括了vue axios请求拦截实例代码的使用技巧和注意事项,需要的朋友参考一下 axios 简介 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征: 从浏览器中创建 XMLHttpRequest 从 node.js 发出 http 请求 支持 Promise API 拦截请求和响应 转换请