Reputation: 11313
I know that a new method for an object can be declare like so:
var MyObject = function() {return new MyObject.prototype};
MyObject.prototype.exists = function() {alert("The object exists.")};
How can I create many methods as a bunch for MyObject instead of one by one?
I have tried:
MyObject.prototype = {
exists: function() {alert("The object exists.")},
isBorn: function() {alert("The object is born.")},
isDead: function() {alert("The object has left our world.")}
}
Calling MyObject.exists()
returns: Uncaught TypeError: MyObject.exists is not a function
I am trying to do something like jQuery does.
jQuery is defined like so:
jQuery = function(selector, context) {included)
return new jQuery.fn.init(selector, context);
}
We don't say var j = new jQuery;
when we call it like jQuery("#foo")
.
Then the files says:
jQuery.fn = jQuery.prototype = {
jquery: version,
constructor: jQuery,
length: 0,
toArray: function() {
return slice.call( this );
}
...
}
Isn't toArray()
a method of the jQuery
object? Why doesn't it show the same error when I call it.
Upvotes: 0
Views: 170
Reputation: 29989
When the jQuery
function is called, you're not creating an instance of jQuery
which is why you don't use the new
keyword. Instead, you're returning an instance of jQuery.fn.init
.
Follow it down and you'll see that the prototype of init being declared:
init.prototype = jQuery.fn;
And the definition for jQuery.fn
is:
jQuery.fn = jQuery.prototype = { ... };
Which means that (new jQuery.fn.init(selector, context))
has all the methods from jQuery.prototype
.
So, toArray
is not a method of the jQuery
object, but rather a method on the prototype of the return value from calling jQuery()
.
You can achieve the same thing in fewer steps by manually assigning the prototype of the return value.
function MyObject() {
var obj = {};
return Object.setPrototypeOf(obj, MyObject.prototype);
}
MyObject.prototype.toArray = function() {};
MyObject().toArray();
Upvotes: 1
Reputation: 29906
The first one is still better because prototype objects have predefined properties (currently only constructor
, but later the standard can be extended), and totally overwriting the prototype object will effectively remove those properties. But still it can be shortened like:
function Foo() {}
const p = Foo.prototype;
console.log(Object.getOwnPropertyNames(p));
p.exists = function() { console.log("exists"); };
p.isBorn = function() { console.log("isBorn"); };
(new Foo).exists();
But hey, it's 2016! We have javascript classes in most major browsers (check compatibility at MDN)!
class Foo {
exists() { console.log("exists"); }
isBorn() { console.log("isBorn"); }
}
(new Foo).exists();
Upvotes: 0
Reputation: 903
You were very close, you just have to create a new instance of the object for it to inherit from its own prototype chain.
var myObj = function () {};
myObj.prototype = {
a: function () { console.log(1) },
b: function () { console.log(2) },
c: function () { console.log(3) }
};
var myObject = new myObj();
myObject.a(); // 1
myObject.b(); // 2
myObject.c(); // 3
Upvotes: 0