3

I want to create a custom image constructor:

var image1 = new imgConstructor("picture.png", 100, 50);

I have tried:

var imgConstructor = function(src, width, height) {
    this = new Image(width, height);
    this.src = src;
}

but this = new Image()is invalid.

I know I can do it with factory function like:

var imgConstructor = function(src, width, height) {
    var img = new Image(width, height);
    img.src = src;
    return img;
}
var image1 = imgConstructor("picture.png", 100, 50);

But I want to do with constructor, using "new". Any ideas?

marirena
  • 300
  • 2
  • 10

3 Answers3

3

But I want to do with constructor, using new. Any ideas?

No, that's not possible. You won't be able to subclass Imageafter all. If you needed "instances" with your own methods, better create a wrapper object (like doing this.img = new Image(…) in your constructor).

Using a factory function is totally fine, it just seems to be appropriate here. If you want to use new for some reason, you can use new on your factory function and it will still work (though yielding the Image, not an instance of imgConstructor).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks, can you explain me what is the disadvantage of "yielding the Image, not an instance of imgConstructor"? – marirena May 01 '15 at 13:55
  • When someone calls `new imgConstructor`, one would usually expect that the result is an instance of `imgConstructor`. It is not always, as when the constructor `return`s an object explicitly that might be something different. – Bergi May 01 '15 at 13:59
1

Inheritance won't help you here. Because Image can't be inherited. See why here

Basic explanation:

var a = new Image();
console.log(a.constructor); // Should be function Image() { [native code] }
// OUTPUT: function HTMLImageElement() { [native code] }

var b = new HTMLImageElement();
// Uncaught TypeError: Illegal constructor

So, your solution is corret.

EDIT: The solution from @user86745458 is working but as @Bergi said:

When someone calls new imgConstructor, one would usually expect that the result is an instance of imgConstructor. It is not always, as when the constructor returns an object explicitly that might be something different.

Try applying the old solution (from @user86745458) and check:

new imgConstructor() instanceof imgConstructor
// OUTPUT: false 
imgConstructor() instanceof imgConstructor
// OUTPUT: false
imgConstructor() instanceof Image
// OUTPUT: true
Community
  • 1
  • 1
Wédney Yuri
  • 1,267
  • 12
  • 21
0

Try to add something like this

var imgConstructor = function(src, width, height) {
    var img = this;
    img = new Image(width, height);
    img.onload = function(){
      // image  has been loaded
    };
    img.src = src;
    return img;
}
Lumi Lu
  • 3,289
  • 1
  • 11
  • 21
  • Nice, but it doesnt return the image I think. I want to return the image object and load it afterwards – marirena May 01 '15 at 13:19
  • 1
    Why it is not working: `var img = this;` Ok, storing the reference to `this` object. `img = new Image(width, height);` Throwing away the last reference and storing a new reference. – Wédney Yuri May 01 '15 at 13:33
  • You added the "return img;" line? Now it's working like a charm. I call it with image1 = new imgConstructor and it works fine. but the line "var img = this" is not needed? I removed it and the function still works – marirena May 01 '15 at 13:43