考虑我需要函数中某个对象属性的值。每当我选择在函数之间传递原始值或对象时 - 我应该选择哪一个?它会影响性能吗?我知道javascript中的对象是通过引用和原语按值传递的,实际上我可以在将值传递给某个函数之前提取一个值,也可以传递一个对象并获取函数内的值。会有什么不同吗?
答案 0 :(得分:2)
从表现的角度来看,没有任何区别。
给出以下功能:
function bar(y) {
return y.x + "A";
}
function foo(x) {
return x + "A";
}
让我们比较两者的生成代码(d8 --print_code
):
kind = FUNCTION
name = foo
Instructions (size = 140)
44 ff7510 push [rbp+0x10]
47 48b8917b41caf2330000 REX.W movq rax,0x33f2ca417b91 ;; object: 0x33f2ca417b91 <String[1]: A>
57 5a pop rdx
58 e8010efbff call 0x2cdacea17520 ;; debug: statement 19
;; debug: position 28
;; code: BINARY_OP_IC, UNINITIALIZED (id = 7)
63 90 nop
64 48bb114b30dff2130000 REX.W movq rbx,0x13f2df304b11 ;; object: 0x13f2df304b11 Cell for 6144
74 83430bd1 addl [rbx+0xb],0xd1
78 791f jns 111 (0x2cdacea6674f)
80 50 push rax
81 e82a45fdff call InterruptCheck (0x2cdacea3ac60) ;; code: BUILTIN
86 58 pop rax
87 48bb114b30dff2130000 REX.W movq rbx,0x13f2df304b11 ;; object: 0x13f2df304b11 Cell for 6144
97 49ba0000000000180000 REX.W movq r10,0x180000000000
107 4c895307 REX.W movq [rbx+0x7],r10
111 488be5 REX.W movq rsp,rbp ;; debug: statement 35
;; js return
和
kind = FUNCTION
name = bar
Instructions (size = 164)
44 488b4510 REX.W movq rax,[rbp+0x10]
48 488bd0 REX.W movq rdx,rax
51 48b9a1d742caf2330000 REX.W movq rcx,0x33f2ca42d7a1 ;; object: 0x33f2ca42d7a1 <String[1]: x>
61 e89e00fdff call 0x2cdacea36940 ;; debug: statement 57
;; debug: position 65
;; code: LOAD_IC, UNINITIALIZED (id = 11)
66 50 push rax
67 48b8917b41caf2330000 REX.W movq rax,0x33f2ca417b91 ;; object: 0x33f2ca417b91 <String[1]: A>
77 5a pop rdx
78 e86d0cfbff call 0x2cdacea17520 ;; debug: position 68
;; code: BINARY_OP_IC, UNINITIALIZED (id = 7)
83 90 nop
84 48bb214b30dff2130000 REX.W movq rbx,0x13f2df304b21 ;; object: 0x13f2df304b21 Cell for 6144
94 83430bd1 addl [rbx+0xb],0xd1
98 791f jns 131 (0x2cdacea668e3)
100 50 push rax
101 e89643fdff call InterruptCheck (0x2cdacea3ac60) ;; code: BUILTIN
106 58 pop rax
107 48bb214b30dff2130000 REX.W movq rbx,0x13f2df304b21 ;; object: 0x13f2df304b21 Cell for 6144
117 49ba0000000000180000 REX.W movq r10,0x180000000000
127 4c895307 REX.W movq [rbx+0x7],r10
131 488be5 REX.W movq rsp,rbp ;; debug: statement 75
;; js return
如您所见,bar
包含一个额外的函数调用(LOAD_IC
,即点)并且还有24个汇编指令。这不是你应该担心的事情。
这是调用foo(obj.x)
的代码:
48b981d712a7a60d0000 REX.W movq rcx,0xda6a712d781 ;; object: 0xda6a712d781 <String[3]: foo>
488b5627 REX.W movq rdx,[rsi+0x27]
e83a03fdff call 0x169fb62368c0 ;; debug: statement 111
;; code: contextual, LOAD_IC, UNINITIALIZED
50 push rax
49ba214140cc39180000 REX.W movq r10,0x1839cc404121 ;; object: 0x1839cc404121 <undefined>
4152 push r10
48b9c1d712a7a60d0000 REX.W movq rcx,0xda6a712d7c1 ;; object: 0xda6a712d7c1 <String[3]: obj>
488b5627 REX.W movq rdx,[rsi+0x27]
e81a03fdff call 0x169fb62368c0 ;; debug: position 115
;; code: contextual, LOAD_IC, UNINITIALIZED
488bd0 REX.W movq rdx,rax
48b9a1d712a7a60d0000 REX.W movq rcx,0xda6a712d7a1 ;; object: 0xda6a712d7a1 <String[1]: x>
e88803fdff call 0x169fb6236940 ;; debug: position 118
;; code: LOAD_IC, UNINITIALIZED (id = 46)
50 push rax
4b8d1464 REX.W leaq rdx,[r12+r12*2]
488b7c2410 REX.W movq rdi,[rsp+0x10]
e8b9f7faff call 0x169fb6215d80 ;; code: CALL_IC, DEFAULT
这是bar(obj)
:
8b981d7a2f60c3e0000 REX.W movq rcx,0x3e0cf6a2d781 ;; object: 0x3e0cf6a2d781 <String[3]: bar>
488b5627 REX.W movq rdx,[rsi+0x27]
e83a03fdff call 0x35b86e8368c0 ;; debug: statement 125
;; code: contextual, LOAD_IC, UNINITIALIZED
50 push rax
49ba214160ee911c0000 REX.W movq r10,0x1c91ee604121 ;; object: 0x1c91ee604121 <undefined>
4152 push r10
48b9e1d7a2f60c3e0000 REX.W movq rcx,0x3e0cf6a2d7e1 ;; object: 0x3e0cf6a2d7e1 <String[3]: obj>
488b5627 REX.W movq rdx,[rsi+0x27]
e81a03fdff call 0x35b86e8368c0 ;; debug: position 129
;; code: contextual, LOAD_IC, UNINITIALIZED
50 push rax
4b8d1464 REX.W leaq rdx,[r12+r12*2]
488b7c2410 REX.W movq rdi,[rsp+0x10]
e8cbf7faff call 0x35b86e815d80 ;; code: CALL_IC, DEFAULT
答案 1 :(得分:1)
考虑我需要函数中某个对象属性的值。
函数是否应该知道它是对象的属性,还是只需要值?该函数是否需要设置属性,还是只需要属性值?该函数是否始终需要属性值?该函数是否需要对象的多个属性?
选择有意义的东西。
它对性能有影响吗?
几乎没有。
答案 2 :(得分:1)
如果有疑问,测试总是好的。我已准备好jsperf test使用与转储中使用的 georg 相同的调用来比较这两种情况。
正如你所看到的那样,Gecko引擎中只存在唯一可见的差异,但我认为它仍然无关紧要,因为我们谈论的是每秒约7M - 约26M的操作。
如果您正在寻找优化措施,这不是一个值得检查的好地方。