1

I came around a method to merge objects

Object.assign({a:1,b:2},{c:3,d:4})

Result is

{a:1,b:2,c:3,d:4}

Now I have a Video DOM Object which have properties like currentTime,duration

So I wanted to merge DOM Video Object with a simple object like this

Object.assign(videoElement,{www:1})

Result is not what I wanted , sometimes its only the video element and sometimes its {www:1}

So I was wondering if there is any method to convert this DOM Video Object to javascript object so that I can merge it with simple javascript objects like this

Object.assign(ConvertToObject(videoElement),{www:1})

So I could create a new object having properties of my own object and video dom element properties
Thanks in advance and If you vote down please let me know why

Waqas Tahir
  • 7,171
  • 5
  • 25
  • 47

3 Answers3

2

Result is not what I wanted , sometimes its only the video element and sometimes its {www:1}

This should not be the case unless you're being inconsistent in your order of arguments.

Object.assign does not create a new object. It modifies and returns the first argument, by coping any directly-assigned enumerable properties over from subsequent argument objects.

Here are some simple examples demonstrating reliable behaviour with DOM elements:

var link = document.createElement('a');
Object.assign(link, { href: 'https://google.com' }) === link;
console.log(link.outerHTML);
<a href="https://google.com"></a>
var vid = document.createElement('video');
Object.assign(link, { src: 'https://example.com/video.mp4' }) === vid;
console.log(link.outerHTML);
<video src="https://example.com/video.mp4"></video>

If you put a different Object as the first argument, it will be returned instead.

If a property isn't being copied, it's probably because it's a "non-enumerable" property. A lot of built-in DOM Element Object properties are non-enumerable, but this isn't DOM-specific. There are non-DOM objects with the same behaviour.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • I want to get all properties of the Video DOM object and sum it up with my object properties and create a new object so even if I change the order I'll not get what I want I want to have vid+link in this case (I mean properties only) – Waqas Tahir Jun 09 '16 at 18:28
  • @Waqas I don't think you've fully thought through what you want here. The video element has a `.parentNode` property, which may have a `.firstChild` property pointing back to the video element. How should that be represented in the result? If you want all properties recursively, you'll capture the entire document. – Jeremy Jun 09 '16 at 18:33
1

You could use for...in to loop all properties and create normal object from HTML element and use Object.assign() to merge two object, here is Fiddle

var vid = document.querySelector('video');

function convertToObject(obj) {
  obj = {}
  for (var p in vid) {
    obj[p] = vid[p];
  }
  return obj;
}

var result = Object.assign(convertToObject(vid), {www: 1});
console.log(result.www);
<video src=""></video>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

DOM objects are not pure JavaScript objects, they are a weird thing called host objects. In short, host objects may behave differently when accessed. They don't have to report their type correctly, nor do they have to claim methods as type function and other such weirdness.

When reading the polyfill method for Object.assign, there are a few lines that might cause trouble on host objects:

if (Object.prototype.hasOwnProperty.call(source, key)) {
    target[key] = source[key];
}

as such, as useful as such a short cut would be, I recommend avoiding it.

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74