Extending an Object in JavaScript

How to extends an object with class in ES6?

I'm not quite sure I understand your need, but it seems like somthing simple like this should suit your needs:

class SomeClass {
constructor(obj) {
Object.assign(this, obj);
// some codes here
}
// some methods here..
}

That way

var obj = new SomeClass({a:1, b:2, c:3, d:4, e:5, f:6});

works just fine.

Javascript composition how to extend an object

First of, state is private. This means we can only do with exposed public methods of TextCell i.e. getHeight and draw.

Now, UnderlineCell is a function that composes over TextCell and extends the implementation for TextCell. e.g.

const getHeight = (state) => ({  getHeight: () => state.text.length})
const draw = (state) => ({ draw: () => state.text.join(" | ")})
const TextCell = (text) => { const state = { text: text.split("\n") }
return Object.assign(getHeight(state), draw(state))}

const UnderlineCell = (text) => { const textCell = TextCell(text); const getHeight = () => textCell.getHeight() + 1; const line = '\n------\n'; const draw = () => textCell.draw().replace(' | ', line) + line;
return {...textCell, getHeight, draw}; }
const uCell = UnderlineCell('hello\nthis');console.log(uCell.draw());

How can I extend properly a JS object?

In the first way, you are replacing the prototype with a new one (overwriting what was there before). In the second way, you are adding a new member to the prototype (thus expanding it).

There is another method: a library that has an extend method or similar (which basically wraps what you're doing in your second form in a nice wrapper). For example, in jQuery:

$.extend(obj_name.prototype, {
newfoo : function() { alert('hi #3'); }
}

Extending a Javascript object without assigning properties to the prototype?

To get things more clearly you should inspect all three ways you've posted with Firebug in Firefox. What the webkit-consoles output there has nothing to do with App.prototype but is the hierarchy of all functions called to setup the command-property. The App.prototype you find under App.__proto__.

With your way 1) you definitely set all properties of object b as own properties of each App instance (= this). These props and also function extend() becomes not part of the App prototype. You can check it out:

console.log(App.prototype);
// or you create an instance of App and search for its prototype:
var myapp = new App(); console.log(Object.getPrototypeOf(myapp));

You achieve exactly the same result as by way 1) when you incorporate function extend() in the App constructor like this:

function App(b) {
if (typeof b == 'object') for (var key in b) this[key] = b[key];
console.log(this);
// Aside: you don't need 'return this', it's done automatically when you use 'new App()'
}
var obj = {command: function () {alert('command!');}};
var myapp = new App(obj);

I would prefer this method because it's easy to rule which App object gets what properties simply by passing them in as argument.

Only with your way 2) function extend() becomes a property of App.prototype because you explicitely define it so. Then its inherited to all App instances.

How to extend javascript objects?

You can use jQuery's $.extend here.

Try following code

var BI = BI || {};
BI = {
firstInit: function () {
console.log('I am first init');
}
}

$.extend(BI, {
init: function () {
console.log('I am init');
}
});

console.log(BI);

Here is the DEMO

Can not extend this JavaScript object

few things you need to take care of,

  1. Use new keyword to create an instance of 'singlyLinkedList'
  2. your terminating condition of while loop is not correct. it should be while( pointer.next )

check below version,

//create a `file.js` file and put this code inside that. running this code snippet on stackoverflow util wont work as you need a separate `file.js`
'use strict';
function singlyLinkedList() { this.head = null;}
singlyLinkedList.prototype.append = function(value) { let node = { data: value, next: null }; if( !this.head ) { this.head = node } else { let pointer = this.head; while( pointer.next ) { //check this pointer = pointer.next } pointer.next = node }};
<!DOCTYPE html><html>  <head>    <title> Test </title>    <meta charset="UTF-8">    <script src="file.js"></script>  </head>  <body>    <script>        let linkedList = new singlyLinkedList(); // check this        let integersArray = [1, 22, 333, 4444];        integersArray.forEach(element => linkedList.append(element));        console.log('linkedList: ', linkedList);
</script> </body></html>

Extending (inherit) class (or object ) in Javascript

You need to define something like this. The first row will create a new object with the properties and methods, which are in BasePage.prototype and set the prototype reference to this, so every LoginPage object will have those properties and objects. After all I add all specific data which is related only to LoginPage (loginPageRelatedMethod). And also it is important to set the proper constructor.

LoginPage.prototype = Object.create(BasePage.prototype);

LoginPage.prototype.constructor = LoginPage;

LoginPage.prototype.loginPageRelatedMethod = function(){
return doSomething;
}

UPDATED

function LoginPage(remote) {
BasePage.call(this, remote);
}

Example

function BasePage(remote) {   this.remote = remote;}
BasePage.prototype = { constructor: BasePage, commonMethodToIntreactWithPage : function() { return 'From Base Page'; }};
function LoginPage(remote) { BasePage.call(this, remote);}
LoginPage.prototype = Object.create(BasePage.prototype);
LoginPage.prototype.constructor = LoginPage;
LoginPage.prototype.loginPageRelatedMethod = function () { return 'From Login Page';}
var loginPage = new LoginPage('Test');console.log(loginPage.commonMethodToIntreactWithPage());

Object.assign vs $.extend

The two key differences are the optional boolean for deep merge which is recursive on the jQuery $.extend method (where false is not supported?!) ...

let object1 = {
id: 1,
name: {
forename: 'John',
surname: 'McClane'
},
};

let object2 = {
id: 2,
name: {
}
};

// merge objects
let objExtend = $.extend(true, {}, object1, object2);
let objAssign = Object.assign({}, object1, object2);

// diff
console.log(objExtend.name.forename); // "John"
console.log(objAssign.name.forename); // undefined

Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

Example: JsFiddle

The second is the $.extend method ignores undefined ...

let object1 = {
id: 1,
name: 'hello world'
};

let object2 = {
id: 2,
name: undefined
};

// merge objects
let objExtend = $.extend({}, object1, object2);
let objAssign = Object.assign({}, object1, object2);

// diff
console.log(objExtend.name); // "hello world"
console.log(objAssign.name); // undefined

Example: JsFiddle

Docs

MDN: Object.assign(target, ...sources)

jQuery: jQuery.extend([deep], target, object1 [, objectN])

Additionally:

If you are looking for a way to deep merge objects without jQuery, this answer is excellent:

How to deep merge instead of shallow merge?

Example: JsFiddle

How to deep merge using Object.assign with ES6:

function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
}

function mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();

if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, ...sources);
}


Related Topics



Leave a reply



Submit