GithubHelp home page GithubHelp logo

Comments (17)

sindresorhus avatar sindresorhus commented on May 10, 2024

I considered it initially, but didn't do it as I wanted an unsurprising default, which is assigning properties, not cloning.

I do see how it could be useful, though. Just not sure how to best support it. Adding support for options isn't possible as the API accepts objects to assign already. Could maybe have a sub-method for this.

But if this were to be supported, wouldn't it make more sense to deep recurse the array too? Meaning recurse into object/arrys in the array.

// @ruffle1986 @schnittstabil

from deep-assign.

jbellsey avatar jbellsey commented on May 10, 2024

Probably my mistake for not fully grasping the subtle distinction between assign and clone.

Might be worth highlighting in the readme that this isn't a clone tool, perhaps with a sample where deep-assign fails unexpectedly. Users needing deep-copy functionality should look to other libraries (e.g.) for that.

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

The behavior is the same as with Object.assign:

> var arr = ['one', 'two', 'three'];
undefined
> var result = Object.assign(arr, [1,2]);
undefined
> result[3] = 4;
4
> arr
[ 1, 2, 'three', 4 ]

Please note that cloning is a very different task and should be done in a different project.
One problem with cloning is the following, which node-clone does also not solve:

> function f() { return 42; }
undefined
> var g = clone(f);
undefined
> g.x = 4;
4
> f.x
4

from deep-assign.

jbellsey avatar jbellsey commented on May 10, 2024

The behavior is the same as with Object.assign

Yes. But, as mentioned, my mistake was in misunderstanding the difference between assign and clone, not between Object.assign and deepAssign.

One problem with cloning is the following, which node-clone does also not solve

I don't consider that a problem. Creating a fresh copy of a function is well past any edge that I've been to. I mean, how do you intend to duplicate its closures and encapsulated data? A shared function pointer is correct behavior IMO, but that discussion is outside the scope of this library in any case.

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

@jbellsey It is only one example of how different cloning and assigning are, to explain why I think that it should be done in a different project.

from deep-assign.

ruffle1986 avatar ruffle1986 commented on May 10, 2024

@jbellsey I made the same mistake and considered deep-assign a cloning tool, but then I realised that it had nothing to do with cloning. To achieve deep cloning, use lodash.clonedeep or deep-extend.

@sindresorhus I wouldn't do any of those you mentioned. It's a different problem which can be solved by other modules like deep-extend. As @schnittstabil has pointed out: deep-assign should do exactly the same as Object.assign does but recursively.

👍 for highlighting it in the readme that it's not a cloning tool.

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

Meaning recurse into object/arrys in the array.

@sindresorhus If I understand you correctly deep-assign already do this:

> var records = [ {id: 1, type: 'leprechaun'} ];
undefined
> deepAssign(records, [ {type: 'unicorn'} ]);
[ { id: 1, type: 'unicorn' } ]

from deep-assign.

sindresorhus avatar sindresorhus commented on May 10, 2024

@schnittstabil No, if so, this would have been false:

var obj = {foo: true};
var x = deepAssign({}, {a: [obj]});
console.log(x.a[0] === obj);
//=> true

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

@sindresorhus In a basic version that would be a strong limitation, e.g.:

function User(name) {
  this.name = name;
}

User.prototype.say = function () {
  return 'Hi I am ' + this.name;
}

var x = deepAssign({}, {users: [new User('Alice'), new User('Bob')]});
console.log(x.users[0] instanceof User);
//=> false
console.log(x.users[0].say);
//=> undefined

from deep-assign.

sindresorhus avatar sindresorhus commented on May 10, 2024

@schnittstabil Agreed, all of this is in the context of an additional option or sub-method, not the main export. Just saying that [].slice() and recursing into it would be useful in many situations, so I'm wondering how and if it should be supported through an option or sub-method.

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

Only-By-Option is cumbersome:

// ES5
var deepAssign = require('deep-assign')();
var myDeepAssign = require('deep-assign')(options);

// ES2015
import DeepAssign from 'deep-assign'; // DeepAssign may not be a constructor though
const deepAssign = DeepAssign();
const myDeepAssign = DeepAssign(options);

We may combine sub-method and options, something like:

var deepAssign = require('deep-assign');
var myDeepAssign = require('deep-assign').createInstance(options);

from deep-assign.

sindresorhus avatar sindresorhus commented on May 10, 2024

If we just forsee there being one variant, for enabling arrays, it could simply just be a sub-method:

var deepAssign = require('deep-assign');
deepAssign.withArray({}, {foo: [{bar: true}]});

Otherwise there are solutions like this if there might be multiple options:

var deepAssign = require('deep-assign');
var opts = deepAssign.opts({array: true});
//    ^ Special DeepAssignOptions object that we check for.

deepAssign({}, {foo: true}, opts);
//=> {foo: true}

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

deepAssign({}, {foo: true}, opts) came also to my mind, but that may change the semantic of deepAssign if opts is an ordinary object.

The benefit would be, that deepAssign({} {a:[1,2]}, opts, {a: [3,4]}) also makes sense.

Hence I considered ES2015 Symbols as flags:

typeof deepAssign.sliceArrays; //=> symbol
deepAssign({}, {foo: true}, deepAssign.sliceArrays, deepAssign.otherOption);

Sadly we can not use a single Symbols as an opts object:

var opts = Symbol('deepAssignOptions');
opts.array = true;
opts.array; //=> undefined

About sub-methods: If we need multiple options some day we may do:

deepAssign.withArray.withOtherOption.withOtherOption2();

But I think this would be unnecessarily hard to maintain.

from deep-assign.

sindresorhus avatar sindresorhus commented on May 10, 2024

deepAssign({}, {foo: true}, opts) came also to my mind, but that may change the semantic of deepAssign if opts is an ordinary object.

Yup, that won't work and why I suggested the special object solution.

Sadly we can not use a single Symbols as an opts object:

We can. The user gets a symbol from us and we compare it to our own symbols internally.

var deepAssign = require('deep-assign');
deepAssign({}, {foo: true}, deepAssign.sliceArrays);
//=> {foo: true}

from deep-assign.

schnittstabil avatar schnittstabil commented on May 10, 2024

@sindresorhus I don't know if there are any major drawbacks on it, but at merge-options I've used this:

mergeOptions(option1, ...options)
mergeOptions.call(config, option1, ...options)

This works mainly via checking this !== undefined and this !== window

from deep-assign.

mightyiam avatar mightyiam commented on May 10, 2024

How about recursive through the children of the array by default (breaking change)?
Would it break many users' usage?

from deep-assign.

sindresorhus avatar sindresorhus commented on May 10, 2024

This module is now deprecated: b332062

from deep-assign.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.