isotropic-mixin
Version:
Mixin function copies property descriptors from one object to another
183 lines (132 loc) • 4.74 kB
Markdown
[](https://www.npmjs.com/package/isotropic-mixin)
[](https://github.com/ibi-group/isotropic-mixin/blob/main/LICENSE)


A utility that copies property descriptors from one object to another, preserving getters, setters, and property attributes.
- **Complete Property Copying**: Copies the entire property descriptor, not just values
- **Preserves Getters & Setters**: Maintains accessors and their shared state
- **Respects Property Attributes**: Preserves configurable, enumerable, and writable settings
- **Simple Implementation**: Uses modern JavaScript reflection APIs for clarity and reliability
```bash
npm install isotropic-mixin
```
```javascript
import _mixin from 'isotropic-mixin';
// Objects to work with
const _source = {
name: 'Source Object',
getValue () {
return 42;
}
},
_target = {
id: 'target-123'
};
// Mix source properties into target
_mixin(_source, _target);
// Target now has all properties from source
console.log(_target.name); // 'Source Object'
console.log(_target.getValue()); // 42
console.log(_target.id); // 'target-123' (original properties remain)
```
`isotropic-mixin` uses the `Reflect` API to:
1. Get all own property names from the source object (including non-enumerable properties)
2. Retrieve the full property descriptor for each property
3. Define each property on the target object with the same descriptor
This approach ensures all property characteristics (such as getters, setters, and property attributes) are preserved during the copy operation.
## API
### mixin(from, to)
Copies all own properties from the source object to the target object.
#### Parameters
- `from` (Object): The source object to copy properties from
- `to` (Object): The target object to copy properties to
#### Returns
- (undefined): The function doesn't return a value, but modifies the target object
## Examples
### Working with Getters and Setters
```javascript
import _mixin from 'isotropic-mixin';
// Source object with getter/setter
const _source = {
get value () {
return this._value;
},
set value (v) {
this._value = v;
},
_value: 0
},
// Target object
_target = {};
// Mix properties
_mixin(_source, _target);
// The getter/setter behavior is preserved
_target.value = 42;
console.log(_target.value); // 42
console.log(_target._value); // 42
// Changes to the internal state are shared
_source.value = 100;
console.log(_target.value); // 100
```
```javascript
import _mixin from 'isotropic-mixin';
const _source = {},
_target = {};
// Source with non-enumerable property
Object.defineProperty(_source, 'hidden', {
enumerable: false,
value: 'I am hidden'
});
// Standard Object.assign doesn't copy non-enumerable properties
Object.assign(_target, _source);
console.log(Object.getOwnPropertyNames(_target)); // []
// isotropic-mixin does copy non-enumerable properties
_mixin(_source, _target);
console.log(Object.getOwnPropertyNames(_target)); // ['hidden']
console.log(target.hidden); // 'I am hidden'
```
```javascript
import _mixin from 'isotropic-mixin';
// Default configuration
const _defaultConfig = {
fontSize: 14,
get isDarkMode () {
return this.theme === 'dark';
}
showNotifications: true,
theme: 'light'
},
// Apply user configuration
_createConfig = userConfig => {
const config = {};
// Apply defaults first
_mixin(_defaultConfig, config);
// Then apply user overrides
if (userConfig) {
_mixin(userConfig, config);
}
return config;
};
{
// Create configurations
const defaultUserConfig = _createConfig();
console.log(defaultUserConfig.theme); // 'light'
console.log(defaultUserConfig.isDarkMode); // false
const darkModeConfig = _createConfig({
theme: 'dark'
});
console.log(darkModeConfig.theme); // 'dark'
console.log(darkModeConfig.isDarkMode); // true
}
```
Please refer to [CONTRIBUTING.md](https://github.com/ibi-group/isotropic-mixin/blob/main/CONTRIBUTING.md) for contribution guidelines.
If you encounter any issues, please file them at https://github.com/ibi-group/isotropic-mixin/issues