Javascript 正在使用缓存的;这";快于;这";当访问同一对象的方法时?

Javascript 正在使用缓存的;这";快于;这";当访问同一对象的方法时?,javascript,performance,Javascript,Performance,如果我从另一个方法多次访问this.something,缓存“this”并访问something()会更快吗?还是应该反复使用this.something() <script type="text/javascript"> var Foo = (function() { return { something: function() { // Do something }, stuff: function(

如果我从另一个方法多次访问this.something,缓存“this”并访问something()会更快吗?还是应该反复使用this.something()

<script type="text/javascript">
var Foo = (function() {
    return {
        something: function() {
            // Do something
        },
        stuff: function(obj) {
            this.something(obj);
            // ...
            this.something(obj);

            /* OR should I cache this? */
            var $that = this;
            $that.something(obj);
            // ...
            $that.something(obj);
        }
    };
}());
</script>

var Foo=(函数(){
返回{
某物:函数(){
//做点什么
},
材料:功能(obj){
这是什么(obj);
// ...
这是什么(obj);
/*或者我应该缓存这个*/
var$that=这个;
$that.something(obj);
// ...
$that.something(obj);
}
};
}());

您只需指向对象引用的副本,而不是直接指向对象引用。我无法想象缓存的速度会有多快——但是,嘿,启动一个测试框架,在循环中执行10000次,看看它是否有什么不同。

这里只有评测可以回答。但是在进行这种微优化之前,问问自己是否真的需要。

我不明白为什么变量应该比
this
更快

有些可能更快但我发现不起作用的方法是缓存整个方法查找。。。e、 g.通过执行
m=object.method。。。m(x,y,z)。例如,这在Python中是可行的(因为绑定方法的概念),但在Javascript中是不可用的

在javascript中查找方法的结果或多或少地给你一些类似C++的方法指针的东西,换句话说,一个不知道代码>这个< <代码>的函数,因此你必须提供<代码>这个< /代码>你自己可以调用它。 <> >唯一的区别是,在C++中,没有声明静态的任何方法都不能被调用,而不提供<代码> < <代码>,而在JavaScript保存中,方法查找显然只适用于在运行时不需要代码> > 按预期执行的方法。 例如
var mycos=Math.cos;霉菌(0.3)至少显然是有效的,因为
cos
不需要访问数学(毕竟这并不奇怪)

您可以得到一个在功能上作为缓存方法工作的闭包

var cachedfoo = obj.foo;
var foo = function(x, y, z) { return cachedfoo.call(obj, x, y, z); }
...
foo(1,2,3); // this is the same as obj.foo(1,2,3)

出于其他原因,这可能是有用的,但在我看来,它不会更快(实际上可能会更慢).

更新:查看下面CMS的评论,了解真实情况(但我认为它不会改变任何性能)


近似真理:

不,没什么区别。在执行函数时,将创建一个激活对象,并将其放在函数范围链的开头(更具体地说,是其执行上下文)

激活对象具有属性
this
arguments
,每个传递的参数和函数中声明的每个变量都有一个属性

因此,
这个
$那个
生活在同一个范围内,你从中什么也得不到。只有在本地引用范围更大的对象/值时,才能得到改进

  +-------------------+     +-------------+
  | Execution Context |  +->| Scope Chain |
  | ----------------- |  |  | ----------- |
  | Scope chain  +----+--+  | 0    |  +---+----------+
  +-------------------+     | 1    |  +---+-...      |
                            +-------------+          |
                                                     |
                                                     |
                                                     |
                            +--------------------+   |
                            |  Activation Object |<--+
                            | ------------------ |
                            | this     |  foo    |  (if called with foo.method())
                            | arguments|[someObj]|
                            | obj      | someObj |
                            | $that    |  foo    | (undefined until assignment)
                            +--------------------+
+-------------++-------------+
|执行上下文|+->|范围链|
| ----------------- |  |  | ----------- |
|范围链+-----++|0|+---+----------+
+-------------------+     | 1    |  +---+-...      |
+-------------+          |
|
|
|
+--------------------+   |

|激活对象|基准测试是确定性能影响的唯一有效方法,是的。但在这种情况下,我敢打赌这不会有任何(明显的)区别。(我对这种方法有一个不同的问题:即使它“快25%”,也不会对99.99%的代码产生任何明显的影响)。我愿意用我的薪水打赌这不会产生任何影响。我还应该指定多次运行…您可以缓存该方法,但您需要使用
.call()
.apply()
为该方法设置
this
的正确值(假设您正在调用的方法中使用了
this
),而不必指定“this”正是绑定方法的概念。避免方法的查找,但添加“call”的查找并没有那么有趣(call和apply可能是出于与速度不同的原因)。类似于
foo=function(x,y,z){return cachedfoo.call(object,x,y,z);}
对于速度IMO:-)来说不会是一个很大的胜利,这是一个很好的观点。它只是将一个属性查找替换为另一个属性查找。主要的一点是,您可以引用一个函数并调用它。要在回答中使用示例,
m=object.method。。。m(x,y,z)将起作用。唯一的区别是,如果调用的方法依赖于
this
,则需要执行
m=object.method。。。m、 调用(这个,x,y,z):o)我并不想对我的评论感到乏味,但我想你的更新速度会慢一些。每次调用
foo
时,您都在创建两个执行上下文,仍然在执行
.call()
的属性查找,并且还必须按照作用域链查找
obj
。这是因为每次调用
foo
时都会计算
cachedfoo.call(obj,x,y,z)
,而不是在将函数分配给
foo
时计算一次。ES5有一个
.bind()
方法,可以消除很多这种情况。总的来说,您的观点是绝对正确的,即缓存
不会提高性能+1看着你,对图表充满幻想;o) +1太好了!我能借一下吗