time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

README.md (6827B)


      1 <!--
      2 
      3 @license Apache-2.0
      4 
      5 Copyright (c) 2018 The Stdlib Authors.
      6 
      7 Licensed under the Apache License, Version 2.0 (the "License");
      8 you may not use this file except in compliance with the License.
      9 You may obtain a copy of the License at
     10 
     11    http://www.apache.org/licenses/LICENSE-2.0
     12 
     13 Unless required by applicable law or agreed to in writing, software
     14 distributed under the License is distributed on an "AS IS" BASIS,
     15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 See the License for the specific language governing permissions and
     17 limitations under the License.
     18 
     19 -->
     20 
     21 # Copy
     22 
     23 > Copy or deep clone a value to an arbitrary depth.
     24 
     25 <section class="usage">
     26 
     27 ## Usage
     28 
     29 ```javascript
     30 var copy = require( '@stdlib/utils/copy' );
     31 ```
     32 
     33 #### copy( value\[, level] )
     34 
     35 Copy or deep clone an input `value` to an arbitrary depth. The function accepts both `objects` and `primitives`.
     36 
     37 ```javascript
     38 // Primitives...
     39 var out = copy( 'beep' );
     40 // returns 'beep'
     41 
     42 // Objects...
     43 var value = [
     44     {
     45         'a': 1,
     46         'b': true,
     47         'c': [ 1, 2, 3 ]
     48     }
     49 ];
     50 out = copy( value );
     51 // returns [ { 'a': 1, 'b': true, 'c': [ 1, 2, 3 ] } ]
     52 
     53 var bool = ( value[0].c === out[0].c );
     54 // returns false
     55 
     56 // Error object...
     57 var err1 = new TypeError( 'beep' );
     58 
     59 var err2 = copy( err1 );
     60 // returns <TypeError>
     61 ```
     62 
     63 The default behavior returns a **full** deep copy of any `object`. To limit the copy depth, set the `level` option.
     64 
     65 ```javascript
     66 var value = [
     67     {
     68         'a': 1,
     69         'b': true,
     70         'c': [ 1, 2, 3 ]
     71     }
     72 ];
     73 
     74 // Trivial case => return the same reference
     75 var out = copy( value, 0 );
     76 // returns [ { 'a': 1, 'b': true, 'c': [ 1, 2, 3 ] } ]
     77 
     78 var bool = ( value[0] === out[0] );
     79 // returns true
     80 
     81 // Shallow copy:
     82 out = copy( value, 1 );
     83 
     84 bool = ( value === out );
     85 // returns false
     86 
     87 bool = ( value[0] === out[0] );
     88 // returns true
     89 
     90 // Deep copy:
     91 out = copy( value, 2 );
     92 
     93 bool = ( value[0] === out[0] );
     94 // returns false
     95 
     96 bool = ( value[0].c === out[0].c );
     97 // returns true
     98 ```
     99 
    100 </section>
    101 
    102 <!-- /.usage -->
    103 
    104 <section class="notes">
    105 
    106 ## Notes
    107 
    108 -   List of **supported** values/types:
    109 
    110     -   `undefined`
    111     -   `null`
    112     -   `boolean`/`Boolean`
    113     -   `string`/`String`
    114     -   `number`/`Number`
    115     -   `function`
    116     -   `Object`
    117     -   `Date`
    118     -   `RegExp`
    119     -   `Set`
    120     -   `Map`
    121     -   [`Error`][mdn-error]
    122     -   [`URIError`][mdn-uri-error]
    123     -   [`ReferenceError`][mdn-reference-error]
    124     -   [`SyntaxError`][mdn-syntax-error]
    125     -   [`RangeError`][mdn-range-error]
    126     -   [`EvalError`][mdn-eval-error]
    127     -   [`TypeError`][mdn-type-error]
    128     -   [`System Error`][node-system-error] (Node.js)
    129     -   `Array`
    130     -   `Int8Array`
    131     -   `Uint8Array`
    132     -   `Uint8ClampedArray`
    133     -   `Init16Array`
    134     -   `Uint16Array`
    135     -   `Int32Array`
    136     -   `Uint32Array`
    137     -   `Float32Array`
    138     -   `Float64Array`
    139     -   `Buffer` ([Node.js][node-buffer])
    140 
    141 -   List of **unsupported** values/types:
    142 
    143     -   `DOMElement`: to copy DOM elements, use `element.cloneNode()`.
    144     -   `Symbol`
    145     -   `WeakMap`
    146     -   `WeakSet`
    147     -   `Blob`
    148     -   `File`
    149     -   `FileList`
    150     -   `ImageData`
    151     -   `ImageBitmap`
    152     -   `ArrayBuffer`
    153 
    154 -   The implementation **can** handle circular references.
    155 
    156 -   If a `Number`, `String`, or `Boolean` object is encountered, the value is cloned as a **primitive**. This behavior is intentional. The implementation is opinionated in wanting to **avoid** creating `numbers`, `strings`, and `booleans` via the `new` operator and a constructor.
    157 
    158 -   For `objects`, the implementation **only** copies `enumerable` keys and their associated property descriptors.
    159 
    160 -   The implementation **only** checks whether basic `Objects`, `Arrays`, and class instances are `extensible`, `sealed`, and/or `frozen`.
    161 
    162 -   `functions` are **not** cloned; their reference is copied.
    163 
    164 -   The implementation supports custom [`error`][mdn-error] types which are [`Error`][mdn-error] instances (e.g., ES2015 subclasses).
    165 
    166 -   Support for copying class instances is inherently **fragile**. Any instances with privileged access to variables (e.g., within closures) cannot be cloned. This stated, basic copying of class instances is supported. Provided an environment which supports ES5, the implementation is greedy and performs a deep clone of any arbitrary class instance and its properties. The implementation assumes that the concept of `level` applies only to the class instance reference, but not to its internal state.
    167 
    168     <!-- eslint-disable no-underscore-dangle -->
    169 
    170     ```javascript
    171     function Foo() {
    172         this._data = [ 1, 2, 3, 4 ];
    173         this._name = 'bar';
    174         return this;
    175     }
    176 
    177     var foo1 = new Foo();
    178     var foo2 = copy( foo1 );
    179 
    180     var bool = ( foo1._name === foo2._name );
    181     // returns true
    182 
    183     bool = ( foo1._data === foo2._data );
    184     // returns false
    185 
    186     bool = ( foo1._data[0] === foo2._data[0] );
    187     // returns true
    188     ```
    189 
    190 </section>
    191 
    192 <!-- /.notes -->
    193 
    194 <section class="examples">
    195 
    196 ## Examples
    197 
    198 <!-- eslint no-undef: "error" -->
    199 
    200 ```javascript
    201 var randu = require( '@stdlib/random/base/randu' );
    202 var Int32Array = require( '@stdlib/array/int32' );
    203 var copy = require( '@stdlib/utils/copy' );
    204 
    205 var arr = [
    206     {
    207         'x': new Date(),
    208         'y': [ randu(), randu() ],
    209         'z': new Int32Array( [ 1, 2, 3, 4 ] ),
    210         'label': 'Beep'
    211     },
    212     {
    213         'x': new Date(),
    214         'y': [ randu(), randu() ],
    215         'z': new Int32Array( [ 3, 1, 2, 4 ] ),
    216         'label': 'Boop'
    217     }
    218 ];
    219 
    220 // Perform a full deep copy:
    221 var out = copy( arr );
    222 
    223 var bool = ( arr[ 0 ] === out[ 0 ] );
    224 // returns false
    225 
    226 bool = ( arr[ 1 ].y === out[ 1 ].y );
    227 // returns false
    228 
    229 // Perform a shallow copy:
    230 out = copy( arr, 1 );
    231 
    232 bool = ( arr[ 0 ] === out[ 0 ] );
    233 // returns true
    234 
    235 bool = ( arr[ 1 ].z === out[ 1 ].z );
    236 // returns true
    237 ```
    238 
    239 </section>
    240 
    241 <!-- /.examples -->
    242 
    243 <section class="links">
    244 
    245 [mdn-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
    246 
    247 [mdn-type-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError
    248 
    249 [mdn-syntax-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError
    250 
    251 [mdn-range-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError
    252 
    253 [mdn-reference-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
    254 
    255 [mdn-uri-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError
    256 
    257 [mdn-eval-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError
    258 
    259 [node-system-error]: https://nodejs.org/api/errors.html#errors_class_system_error
    260 
    261 [node-buffer]: http://nodejs.org/api/buffer.html
    262 
    263 </section>
    264 
    265 <!-- /.links -->