├── .editorconfig
├── .eslintrc.json
├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── .travis.yml
├── .verb.md
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org/
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [{**/{actual,fixtures,expected,templates}/**,*.md}]
13 | trim_trailing_whitespace = false
14 | insert_final_newline = false
15 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "eslint:recommended"
4 | ],
5 |
6 | "env": {
7 | "browser": false,
8 | "es6": true,
9 | "node": true,
10 | "mocha": true
11 | },
12 |
13 | "parserOptions":{
14 | "ecmaVersion": 9,
15 | "sourceType": "module",
16 | "ecmaFeatures": {
17 | "modules": true,
18 | "experimentalObjectRestSpread": true
19 | }
20 | },
21 |
22 | "globals": {
23 | "document": false,
24 | "navigator": false,
25 | "window": false
26 | },
27 |
28 | "rules": {
29 | "accessor-pairs": 2,
30 | "arrow-spacing": [2, { "before": true, "after": true }],
31 | "block-spacing": [2, "always"],
32 | "brace-style": [2, "1tbs", { "allowSingleLine": true }],
33 | "comma-dangle": [2, "never"],
34 | "comma-spacing": [2, { "before": false, "after": true }],
35 | "comma-style": [2, "last"],
36 | "constructor-super": 2,
37 | "curly": [2, "multi-line"],
38 | "dot-location": [2, "property"],
39 | "eol-last": 2,
40 | "eqeqeq": [2, "allow-null"],
41 | "generator-star-spacing": [2, { "before": true, "after": true }],
42 | "handle-callback-err": [2, "^(err|error)$" ],
43 | "indent": [2, 2, { "SwitchCase": 1 }],
44 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
45 | "keyword-spacing": [2, { "before": true, "after": true }],
46 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
47 | "new-parens": 2,
48 | "no-array-constructor": 2,
49 | "no-caller": 2,
50 | "no-class-assign": 2,
51 | "no-cond-assign": 2,
52 | "no-const-assign": 2,
53 | "no-control-regex": 2,
54 | "no-debugger": 2,
55 | "no-delete-var": 2,
56 | "no-dupe-args": 2,
57 | "no-dupe-class-members": 2,
58 | "no-dupe-keys": 2,
59 | "no-duplicate-case": 2,
60 | "no-empty-character-class": 2,
61 | "no-eval": 2,
62 | "no-ex-assign": 2,
63 | "no-extend-native": 2,
64 | "no-extra-bind": 2,
65 | "no-extra-boolean-cast": 2,
66 | "no-extra-parens": [2, "functions"],
67 | "no-fallthrough": 2,
68 | "no-floating-decimal": 2,
69 | "no-func-assign": 2,
70 | "no-implied-eval": 2,
71 | "no-inner-declarations": [2, "functions"],
72 | "no-invalid-regexp": 2,
73 | "no-irregular-whitespace": 2,
74 | "no-iterator": 2,
75 | "no-label-var": 2,
76 | "no-labels": 2,
77 | "no-lone-blocks": 2,
78 | "no-mixed-spaces-and-tabs": 2,
79 | "no-multi-spaces": 2,
80 | "no-multi-str": 2,
81 | "no-multiple-empty-lines": [2, { "max": 1 }],
82 | "no-native-reassign": 0,
83 | "no-negated-in-lhs": 2,
84 | "no-new": 2,
85 | "no-new-func": 2,
86 | "no-new-object": 2,
87 | "no-new-require": 2,
88 | "no-new-wrappers": 2,
89 | "no-obj-calls": 2,
90 | "no-octal": 2,
91 | "no-octal-escape": 2,
92 | "no-proto": 0,
93 | "no-redeclare": 2,
94 | "no-regex-spaces": 2,
95 | "no-return-assign": 2,
96 | "no-self-compare": 2,
97 | "no-sequences": 2,
98 | "no-shadow-restricted-names": 2,
99 | "no-spaced-func": 2,
100 | "no-sparse-arrays": 2,
101 | "no-this-before-super": 2,
102 | "no-throw-literal": 2,
103 | "no-trailing-spaces": 0,
104 | "no-undef": 2,
105 | "no-undef-init": 2,
106 | "no-unexpected-multiline": 2,
107 | "no-unneeded-ternary": [2, { "defaultAssignment": false }],
108 | "no-unreachable": 2,
109 | "no-unused-vars": [2, { "vars": "all", "args": "none" }],
110 | "no-useless-call": 0,
111 | "no-with": 2,
112 | "one-var": [0, { "initialized": "never" }],
113 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
114 | "padded-blocks": [0, "never"],
115 | "quotes": [2, "single", "avoid-escape"],
116 | "radix": 2,
117 | "semi": [2, "always"],
118 | "semi-spacing": [2, { "before": false, "after": true }],
119 | "space-before-blocks": [2, "always"],
120 | "space-before-function-paren": [2, "never"],
121 | "space-in-parens": [2, "never"],
122 | "space-infix-ops": 2,
123 | "space-unary-ops": [2, { "words": true, "nonwords": false }],
124 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
125 | "use-isnan": 2,
126 | "valid-typeof": 2,
127 | "wrap-iife": [2, "any"],
128 | "yoda": [2, "never"]
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Enforce Unix newlines
2 | * text eol=lf
3 |
4 | # binaries
5 | *.ai binary
6 | *.psd binary
7 | *.jpg binary
8 | *.gif binary
9 | *.png binary
10 | *.jpeg binary
11 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: jonschlinkert
2 |
3 | # Tidelift offers a subscription if your organization would benefit from professional support
4 | tidelift: npm/shallow-clone
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # always ignore files
2 | *.DS_Store
3 | .idea
4 | .vscode
5 | *.sublime-*
6 |
7 | # test related, or directories generated by tests
8 | test/actual
9 | actual
10 | coverage
11 | .nyc*
12 |
13 | # npm
14 | node_modules
15 | npm-debug.log
16 |
17 | # yarn
18 | yarn.lock
19 | yarn-error.log
20 |
21 | # misc
22 | _gh_pages
23 | _draft
24 | _drafts
25 | bower_components
26 | vendor
27 | temp
28 | tmp
29 | TODO.md
30 | package-lock.json
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | os:
3 | - linux
4 | - osx
5 | - windows
6 | language: node_js
7 | node_js:
8 | - node
9 | - '11'
10 | - '10'
11 | - '9'
12 | - '8'
13 |
--------------------------------------------------------------------------------
/.verb.md:
--------------------------------------------------------------------------------
1 | ## Usage
2 |
3 | ```js
4 | const clone = require('{%= name %}');
5 | ```
6 |
7 | **Supports**
8 |
9 | - array buffers
10 | - arrays
11 | - buffers
12 | - dates
13 | - errors
14 | - float32 arrays
15 | - float64 arrays
16 | - int16 arrays
17 | - int32 arrays
18 | - int8 arrays
19 | - maps
20 | - objects
21 | - primitives
22 | - regular expressions
23 | - sets
24 | - symbols
25 | - uint16 arrays
26 | - uint32 arrays
27 | - uint8 arrays
28 | - uint8clamped arrays
29 |
30 |
31 | ## Arrays
32 |
33 | By default, only the array itself is cloned (shallow), use [clone-deep][] if you also need the elements in the array to be cloned.
34 |
35 | ```js
36 | const arr = [{ a: 0 }, { b: 1 }];
37 | const foo = clone(arr);
38 | // foo => [{ 'a': 0 }, { 'b': 1 }]
39 |
40 | // array is cloned
41 | assert(actual === expected); // false
42 |
43 | // array elements are not
44 | assert.deepEqual(actual[0], expected[0]); // true
45 | ```
46 |
47 | ## Objects
48 |
49 | Only the object is shallow cloned, use [clone-deep][] if you also need the values in the object to be cloned.
50 |
51 | ```js
52 | console.log(clone({ a: 1, b: 2, c: 3 }));
53 | //=> {a: 1, b: 2, c: 3 }
54 | ```
55 |
56 |
57 | ## RegExp
58 |
59 | Clones regular expressions and flags, and preserves the `.lastIndex`.
60 |
61 | ```js
62 | const regex = clone(/foo/g); //=> /foo/g
63 | // you can manually reset lastIndex if necessary
64 | regex.lastIndex = 0;
65 | ```
66 |
67 | ## Primitives
68 |
69 | Simply returns primitives unchanged.
70 |
71 | ```js
72 | clone(0); //=> 0
73 | clone('foo'); //=> 'foo'
74 | ```
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-present, Jon Schlinkert.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # shallow-clone [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/shallow-clone) [](https://npmjs.org/package/shallow-clone) [](https://npmjs.org/package/shallow-clone) [](https://travis-ci.org/jonschlinkert/shallow-clone)
2 |
3 | > Creates a shallow clone of any JavaScript value.
4 |
5 | Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
6 |
7 | ## Install
8 |
9 | Install with [npm](https://www.npmjs.com/):
10 |
11 | ```sh
12 | $ npm install --save shallow-clone
13 | ```
14 |
15 | ## Usage
16 |
17 | ```js
18 | const clone = require('shallow-clone');
19 | ```
20 |
21 | **Supports**
22 |
23 | * array buffers
24 | * arrays
25 | * buffers
26 | * dates
27 | * errors
28 | * float32 arrays
29 | * float64 arrays
30 | * int16 arrays
31 | * int32 arrays
32 | * int8 arrays
33 | * maps
34 | * objects
35 | * primitives
36 | * regular expressions
37 | * sets
38 | * symbols
39 | * uint16 arrays
40 | * uint32 arrays
41 | * uint8 arrays
42 | * uint8clamped arrays
43 |
44 | ## Arrays
45 |
46 | By default, only the array itself is cloned (shallow), use [clone-deep](https://github.com/jonschlinkert/clone-deep) if you also need the elements in the array to be cloned.
47 |
48 | ```js
49 | const arr = [{ a: 0 }, { b: 1 }];
50 | const foo = clone(arr);
51 | // foo => [{ 'a': 0 }, { 'b': 1 }]
52 |
53 | // array is cloned
54 | assert(actual === expected); // false
55 |
56 | // array elements are not
57 | assert.deepEqual(actual[0], expected[0]); // true
58 | ```
59 |
60 | ## Objects
61 |
62 | Only the object is shallow cloned, use [clone-deep](https://github.com/jonschlinkert/clone-deep) if you also need the values in the object to be cloned.
63 |
64 | ```js
65 | console.log(clone({ a: 1, b: 2, c: 3 }));
66 | //=> {a: 1, b: 2, c: 3 }
67 | ```
68 |
69 | ## RegExp
70 |
71 | Clones regular expressions and flags, and preserves the `.lastIndex`.
72 |
73 | ```js
74 | const regex = clone(/foo/g); //=> /foo/g
75 | // you can manually reset lastIndex if necessary
76 | regex.lastIndex = 0;
77 | ```
78 |
79 | ## Primitives
80 |
81 | Simply returns primitives unchanged.
82 |
83 | ```js
84 | clone(0); //=> 0
85 | clone('foo'); //=> 'foo'
86 | ```
87 |
88 | ## About
89 |
90 |
91 | Contributing
92 |
93 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
94 |
95 |
96 |
97 |
98 | Running Tests
99 |
100 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
101 |
102 | ```sh
103 | $ npm install && npm test
104 | ```
105 |
106 |
107 |
108 |
109 | Building docs
110 |
111 | _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
112 |
113 | To generate the readme, run the following command:
114 |
115 | ```sh
116 | $ npm install -g verbose/verb#dev verb-generate-readme && verb
117 | ```
118 |
119 |
120 |
121 | ### Related projects
122 |
123 | You might also be interested in these projects:
124 |
125 | * [assign-deep](https://www.npmjs.com/package/assign-deep): Deeply assign the values of all enumerable-own-properties and symbols from one or more source objects… [more](https://github.com/jonschlinkert/assign-deep) | [homepage](https://github.com/jonschlinkert/assign-deep "Deeply assign the values of all enumerable-own-properties and symbols from one or more source objects to a target object. Returns the target object.")
126 | * [clone-deep](https://www.npmjs.com/package/clone-deep): Recursively (deep) clone JavaScript native types, like Object, Array, RegExp, Date as well as primitives. | [homepage](https://github.com/jonschlinkert/clone-deep "Recursively (deep) clone JavaScript native types, like Object, Array, RegExp, Date as well as primitives.")
127 | * [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object "Returns true if an object was created by the `Object` constructor.")
128 | * [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of "Get the native type of a value.")
129 |
130 | ### Contributors
131 |
132 | | **Commits** | **Contributor** |
133 | | --- | --- |
134 | | 20 | [jonschlinkert](https://github.com/jonschlinkert) |
135 | | 2 | [doowb](https://github.com/doowb) |
136 | | 1 | [jakub-g](https://github.com/jakub-g) |
137 |
138 | ### Author
139 |
140 | **Jon Schlinkert**
141 |
142 | * [GitHub Profile](https://github.com/jonschlinkert)
143 | * [Twitter Profile](https://twitter.com/jonschlinkert)
144 | * [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
145 |
146 | ### License
147 |
148 | Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
149 | Released under the [MIT License](LICENSE).
150 |
151 | ***
152 |
153 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 15, 2019._
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * shallow-clone
3 | *
4 | * Copyright (c) 2015-present, Jon Schlinkert.
5 | * Released under the MIT License.
6 | */
7 |
8 | 'use strict';
9 |
10 | const valueOf = Symbol.prototype.valueOf;
11 | const typeOf = require('kind-of');
12 |
13 | function clone(val, deep) {
14 | switch (typeOf(val)) {
15 | case 'array':
16 | return val.slice();
17 | case 'object':
18 | return Object.assign({}, val);
19 | case 'date':
20 | return new val.constructor(Number(val));
21 | case 'map':
22 | return new Map(val);
23 | case 'set':
24 | return new Set(val);
25 | case 'buffer':
26 | return cloneBuffer(val);
27 | case 'symbol':
28 | return cloneSymbol(val);
29 | case 'arraybuffer':
30 | return cloneArrayBuffer(val);
31 | case 'float32array':
32 | case 'float64array':
33 | case 'int16array':
34 | case 'int32array':
35 | case 'int8array':
36 | case 'uint16array':
37 | case 'uint32array':
38 | case 'uint8clampedarray':
39 | case 'uint8array':
40 | return cloneTypedArray(val);
41 | case 'regexp':
42 | return cloneRegExp(val);
43 | case 'error':
44 | return Object.create(val);
45 | default: {
46 | return val;
47 | }
48 | }
49 | }
50 |
51 | function cloneRegExp(val) {
52 | const flags = val.flags !== void 0 ? val.flags : (/\w+$/.exec(val) || void 0);
53 | const re = new val.constructor(val.source, flags);
54 | re.lastIndex = val.lastIndex;
55 | return re;
56 | }
57 |
58 | function cloneArrayBuffer(val) {
59 | const res = new val.constructor(val.byteLength);
60 | new Uint8Array(res).set(new Uint8Array(val));
61 | return res;
62 | }
63 |
64 | function cloneTypedArray(val, deep) {
65 | return new val.constructor(val.buffer, val.byteOffset, val.length);
66 | }
67 |
68 | function cloneBuffer(val) {
69 | const len = val.length;
70 | const buf = Buffer.allocUnsafe ? Buffer.allocUnsafe(len) : Buffer.from(len);
71 | val.copy(buf);
72 | return buf;
73 | }
74 |
75 | function cloneSymbol(val) {
76 | return valueOf ? Object(valueOf.call(val)) : {};
77 | }
78 |
79 | /**
80 | * Expose `clone`
81 | */
82 |
83 | module.exports = clone;
84 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shallow-clone",
3 | "description": "Creates a shallow clone of any JavaScript value.",
4 | "version": "3.0.1",
5 | "homepage": "https://github.com/jonschlinkert/shallow-clone",
6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
7 | "contributors": [
8 | "Brian Woodward (https://twitter.com/doowb)",
9 | "Jon Schlinkert (http://twitter.com/jonschlinkert)"
10 | ],
11 | "repository": "jonschlinkert/shallow-clone",
12 | "bugs": {
13 | "url": "https://github.com/jonschlinkert/shallow-clone/issues"
14 | },
15 | "license": "MIT",
16 | "files": [
17 | "index.js"
18 | ],
19 | "main": "index.js",
20 | "engines": {
21 | "node": ">=8"
22 | },
23 | "scripts": {
24 | "test": "mocha"
25 | },
26 | "dependencies": {
27 | "kind-of": "^6.0.2"
28 | },
29 | "devDependencies": {
30 | "gulp-format-md": "^2.0.0",
31 | "mocha": "^6.1.3"
32 | },
33 | "keywords": [
34 | "array",
35 | "clone",
36 | "copy",
37 | "extend",
38 | "mixin",
39 | "object",
40 | "primitive",
41 | "shallow"
42 | ],
43 | "verb": {
44 | "toc": false,
45 | "layout": "default",
46 | "tasks": [
47 | "readme"
48 | ],
49 | "plugins": [
50 | "gulp-format-md"
51 | ],
52 | "lint": {
53 | "reflinks": true
54 | },
55 | "related": {
56 | "list": [
57 | "assign-deep",
58 | "clone-deep",
59 | "is-plain-object",
60 | "kind-of"
61 | ]
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('mocha');
4 | const assert = require('assert').strict;
5 | const clone = require('./');
6 |
7 | describe('clone()', () => {
8 | describe('objects', () => {
9 | it('should shallow clone an array of primitives', () => {
10 | assert.deepEqual(clone(['alpha', 'beta', 'gamma']), ['alpha', 'beta', 'gamma']);
11 | });
12 |
13 | it('should shallow clone an array with varied elements', () => {
14 | const val = [0, 'a', {}, [{}], [function() {}], function() {}];
15 | assert.deepEqual(clone(val), val);
16 | });
17 |
18 | it('should clone Map', () => {
19 | const a = new Map([[1, 5]]);
20 | const b = clone(a);
21 | a.set(2, 4);
22 | assert.notDeepEqual(a, b);
23 | });
24 |
25 | it('should clone Set', () => {
26 | const a = new Set([2, 1, 3]);
27 | const b = clone(a);
28 | a.add(8);
29 | assert.notDeepEqual(a, b);
30 | });
31 |
32 | it('should shallow clone arrays', () => {
33 | assert(clone([1, 2, 3]) !== [1, 2, 3]);
34 | assert.deepEqual(clone([1, 2, 3]), [1, 2, 3]);
35 | });
36 |
37 | it('should shallow clone a regex with flags', () => {
38 | assert(clone(/foo/g) !== /foo/g);
39 | assert.deepEqual(clone(/foo/g), /foo/g);
40 | });
41 |
42 | it('should shallow clone a regex without any flags', () => {
43 | assert(clone(/foo/) !== /foo/);
44 | assert.deepEqual(clone(/foo/), /foo/);
45 | });
46 |
47 | it('should shallow clone a date', () => {
48 | const date = new Date();
49 | assert(clone(date) !== date);
50 | assert.deepEqual(clone(date), date);
51 | });
52 |
53 | it('should shallow clone objects', () => {
54 | assert.deepEqual(clone({ a: 1, b: 2, c: 3 }), { a: 1, b: 2, c: 3 });
55 | });
56 |
57 | it('should shallow clone an array of objects.', () => {
58 | const expected = [{ a: 0 }, { b: 1 }];
59 | const actual = clone(expected);
60 |
61 | assert(actual !== expected);
62 | assert.deepEqual(actual, expected);
63 | assert.deepEqual(actual[0], expected[0]);
64 | });
65 | });
66 |
67 | describe('primitives', () => {
68 | it('should return primitives', () => {
69 | assert.equal(clone(0), 0);
70 | assert.equal(clone(1), 1);
71 | assert.equal(clone('foo'), 'foo');
72 | });
73 |
74 | it('should clone symbols', () => {
75 | const val = { prop: Symbol() };
76 | const cloned = clone(val);
77 | assert.equal(typeof cloned.prop, 'symbol');
78 | assert.notEqual(cloned, val);
79 | assert.equal(cloned.prop, val.prop);
80 | });
81 | });
82 | });
83 |
--------------------------------------------------------------------------------