# Yes, this is 100% possible with JavaScript!
You can Skip to the end for the solution directly or read this for a detailed explanation.
## The Approach
The solution depends on how you want to implement it as the runtime environment comes into play. Browsers implement runtime environments that enforce ECMAScript standards they adopt while Node.js is a fork on V8 and has it's own modules that deals with how standard
Below, I will take a use case and give two solutions and direct solution to the example problem of your question:
1. **An Universal Solution** that you can implement and it will work on the browser AND on Node.js
2. **Node.js** specific solution.
3. **Solution to the exact Use Case of OP**.
> **Note:** This will also help those studying Data Structures and trying to do a JavaScript implementation.
---
## The Problem
Let's take a Use Case similar to the OP's use case to understand this better. Suppose you are building the Array Data Structure from scratch as a custom **`xArray`** constructor. For simplicity let's only implement the `push` method so we can push some data and then try to output the result exactly the way the JavaScript Array constructor creates objects and the prints the array when we `console.log` the object or return it from a function.
We will also need the static method `XArray.isArray(input)` so we can test if the instance of the object is the same as the constructor.
If we simply `console.log` the Object without adding the solution, we will get something that looks like:
**Undesired Solution:**
```es6
const xArray = new XArray();
xArray.push('a', 'b', 'c', 'd', 'e');
console.log(xArray);
// Prints: XArray { '0': 'a', '1': 'b', '2': 'c', '3': 'd', '4': 'e' }
```
But that's not what we want. We need the `Object.values(xArray)` just like in the OP's use case, `user.name` is required as the output and not the whole `User { name: 'example', password: 'password' }`
So, instead, this is the output we want:
**Desired Solution:**
```es6
// Test function that takes an array and returns it.
const returnArr = array => array;
/************************************************************************************************/
/** Array using custom XArray constructor **/
/************************************************************************************************/
const xArray = new XArray();
xArray.push('a', 'b', 'c', 'd', 'e');
console.log(xArray); // Prints: [ 'a', 'b', 'c', 'd', 'e' ]
console.log(returnArr(xArray)); // Returns: [ 'a', 'b', 'c', 'd', 'e' ]
console.log(XArray.isArray(xArray)); // Returns: true
```
Let's build the solution for the array and then simply implement that for the OP's question.
---
## The Solution
### Solution 1 - `Universal Solution` for all Runtimes
We will modify the `console.log()` inside the constructor function by modifying global object that has the `log` method.
> P.S. - You can `console.log(console)` to see all the console methods.
```
class XArray {
constructor() {
Object.defineProperties(this, {
length: {
writable: true,
enumerable: false,
configurable: false,
value: 0,
},
});
const runtimeConsole = console;
console = {
...console,
log: function (data) {
if (XArray.isArray(data)) runtimeConsole.log(Object.values(data));
else runtimeConsole.log(data);
},
};
}
push(...elements) {
for (const element of elements) {
this[this.length] = element;
this.length++;
}
}
static isArray(array) {
return array instanceof XArray;
}
}
```
---
### Solution 2: For `Node.js` using `util` module
We will be using the [`util.inspect.custom`][1] Symbol from the `util` module in `node.js`.
```
import util from 'util';
class XArray {
constructor() {
Object.defineProperties(this, {
length: {
writable: true,
enumerable: false,
configurable: false,
value: 0,
},
});
}
push(...elements) {
for (const element of elements) {
this[this.length] = element;
this.length++;
}
}
[util.inspect.custom]() {
return Object.values(this);
}
}
```
---
### Solution 3: Solving the OP's Use Case
So you can use either Solution 1 or Solution 2 to solve your Use Case:
#### Solution 3A: `Universal Solution` Using Solution 1
```es6
class User {
constructor(name, password) {
this.name = name;
this.password = password;
const runtimeConsole = console;
console = {
...console,
log: function (data) {
if (User.isUser(data)) runtimeConsole.log(data.name);
else runtimeConsole.log(data);
},
};
}
static isUser(user) {
return user instanceof User;
}
}
```
---
#### Solution 3B: For `Node.js` Using Solution 2
```es6
import util from 'util';
function User(name, password) {
this.name = name;
this.password = password;
[util.inspect.custom]() {
return this.name;
}
}
```
#### Testing Solution 3A and 3B:
```es6
// Test function that takes an user and returns it
const user = new User('example', 'password');
// Function that takes an user and returns it
const returnUser = user => user;
console.log(user); // Prints: example
console.log(returnUser(user)); // Prints: example
```
> **Sidenote**:
> - `import` is an ES6 convention that will not work in Node.js by default unless you have the `package.json` file have a `"type": "module"` setting enabled. This is because Node by default honours the CommonJS convention.
> If this is confusing, replace the import line and use:
> `const util = require('util');`
[1]:
[To see links please register here]