@@ -21,10 +21,28 @@ const {
2121// `uncurryThis` is equivalent to `func => Function.prototype.call.bind(func)`.
2222// It is using `bind.bind(call)` to avoid using `Function.prototype.bind`
2323// and `Function.prototype.call` after it may have been mutated by users.
24- const { bind, call } = Function . prototype ;
24+ const { apply , bind, call } = Function . prototype ;
2525const uncurryThis = bind . bind ( call ) ;
2626primordials . uncurryThis = uncurryThis ;
2727
28+ const applyBind = bind . bind ( apply ) ;
29+ primordials . applyBind = applyBind ;
30+
31+ // Methods that accept a variable number of arguments, and thus it's useful to
32+ // also create `${prefix}${key}Apply`, which uses `Function.prototype.apply`,
33+ // instead of `Function.prototype.call`, and thus doesn't require iterator
34+ // destructuring.
35+ const varargsMethods = [
36+ 'ArrayPrototypePush' ,
37+ 'ArrayPrototypeUnshift' ,
38+ 'ArrayOf' ,
39+ 'MathMax' ,
40+ 'MathMin' ,
41+ 'MathHypot' ,
42+ 'StringPrototypeConcat' ,
43+ 'TypedArrayOf' ,
44+ ] ;
45+
2846function getNewKey ( key ) {
2947 return typeof key === 'symbol' ?
3048 `Symbol${ key . description [ 7 ] . toUpperCase ( ) } ${ key . description . slice ( 8 ) } ` :
@@ -51,7 +69,13 @@ function copyPropsRenamed(src, dest, prefix) {
5169 if ( 'get' in desc ) {
5270 copyAccessor ( dest , prefix , newKey , desc ) ;
5371 } else {
54- ReflectDefineProperty ( dest , `${ prefix } ${ newKey } ` , desc ) ;
72+ const name = `${ prefix } ${ newKey } ` ;
73+ ReflectDefineProperty ( dest , name , desc ) ;
74+ if ( varargsMethods . includes ( name ) ) {
75+ ReflectDefineProperty ( dest , `${ name } Apply` , {
76+ value : applyBind ( desc . value , src ) ,
77+ } ) ;
78+ }
5579 }
5680 }
5781}
@@ -63,10 +87,18 @@ function copyPropsRenamedBound(src, dest, prefix) {
6387 if ( 'get' in desc ) {
6488 copyAccessor ( dest , prefix , newKey , desc ) ;
6589 } else {
66- if ( typeof desc . value === 'function' ) {
67- desc . value = desc . value . bind ( src ) ;
90+ const { value } = desc ;
91+ if ( typeof value === 'function' ) {
92+ desc . value = value . bind ( src ) ;
93+ }
94+
95+ const name = `${ prefix } ${ newKey } ` ;
96+ ReflectDefineProperty ( dest , name , desc ) ;
97+ if ( varargsMethods . includes ( name ) ) {
98+ ReflectDefineProperty ( dest , `${ name } Apply` , {
99+ value : applyBind ( value , src ) ,
100+ } ) ;
68101 }
69- ReflectDefineProperty ( dest , `${ prefix } ${ newKey } ` , desc ) ;
70102 }
71103 }
72104}
@@ -78,10 +110,18 @@ function copyPrototype(src, dest, prefix) {
78110 if ( 'get' in desc ) {
79111 copyAccessor ( dest , prefix , newKey , desc ) ;
80112 } else {
81- if ( typeof desc . value === 'function' ) {
82- desc . value = uncurryThis ( desc . value ) ;
113+ const { value } = desc ;
114+ if ( typeof value === 'function' ) {
115+ desc . value = uncurryThis ( value ) ;
116+ }
117+
118+ const name = `${ prefix } ${ newKey } ` ;
119+ ReflectDefineProperty ( dest , name , desc ) ;
120+ if ( varargsMethods . includes ( name ) ) {
121+ ReflectDefineProperty ( dest , `${ name } Apply` , {
122+ value : applyBind ( value , src ) ,
123+ } ) ;
83124 }
84- ReflectDefineProperty ( dest , `${ prefix } ${ newKey } ` , desc ) ;
85125 }
86126 }
87127}
0 commit comments