Overriding toString prototype inside object declaration - javascript

There was a question on here already about overriding toString and the answer is this:
function Foo() {}
Foo.prototype.toString = function()
{
return "this is Foo";
}
However my question is:
Is there a way to put this prototype override INSIDE of the object declaration like so:
function Foo() {
Foo.prototype.toString = function(){
return "this is Foo";
}
}
Or like so:
var Foo = {
Foo.prototype.toString = function(){
return "this is Foo";
}
}
It's really weird/annoying to have to put the prototype outside of the object declaration, but maybe this is a quirk of JavaScript. I have been wondering this for awhile.

As Ted Hopp mentions, there is no other way to do this yet. In ECMAScript 6 you will be able to use the class syntax, which is just syntactict sugar for constuctor functions and prototypes:
class Foo {
toString() { ... }
}
For object literals, there will also be a shorthand:
var foo = {
__proto__: {
toString() {...}
}
};
The special __proto__ declaration allows you to define the prototype inside the object literal. However, since the protoype is only really useful when it is shared by multiple onjects, directly assigning the property to the object instead would be simpler in this case, and also works today already:
var foo = {
toString: function() {},
};

I think you are searching for bellow
function Foo() {
this.toString = function() {
return "this is Foo";
}
}
Note:- A drawback of this way is that the method toString() is recreated every time you create a new instance of Foo.

There's no good way to do what you want. The Function object Foo (which is usually an object constructor) doesn't exist until the declaration is evaluated, so there's no prototype available for assigning a toString property. Furthermore, the toString assignment won't be evaluated until the constructor is executed at least once.
In any case, you don't want to be initializing the toString property of the prototype inside the constructor because that will assign a new function for each instance of Foo that is created. You could test whether the prototype already has its own toString property already, but this makes the cure worse than the disease. Just stick to the recipe.

There is no way to do that because at the time you are referencing Foo inside the object, Foo hasn't been declared yet. You could try doing this instead.
var Foo = {}; //assign Foo to an empty object.
and then add various properties/methods to Foo using the Object.defineProperties and Object.assign depending on what you want.

function Foo() {
return {
toString: function () {
return "this is foo";
}
};
}
var foo = new Foo();
console.log(foo.toString());

Related

Property of object not returning the expected value in Javascript [duplicate]

In C++, the language I'm most comfortable with, usually one declares an object like this:
class foo
{
public:
int bar;
int getBar() { return bar; }
}
Calling getBar() works fine (ignoring the fact that bar might be uninitialized). The variable bar within getBar() is in the scope of class foo, so I don't need to say this->bar unless I really need to make it clear that I'm referring to the class' bar instead of, say, a parameter.
Now, I'm trying to get started with OOP in Javascript. So, I look up how to define classes and try the same sort of thing:
function foo()
{
this.bar = 0;
this.getBar = function() { return bar; }
}
And it gives me bar is undefined. Changing the bar to this.bar fixes the issue, but doing that for every variable clutters up my code quite a bit. Is this necessary for every variable? Since I can't find any questions relating to this, it makes me feel like I'm doing something fundamentally wrong.
EDIT: Right, so, from the comments what I'm getting is that this.bar, a property of an object, references something different than bar, a local variable. Can someone say why exactly this is, in terms of scoping and objects, and if there's another way to define an object where this isn't necessary?
JavaScript has no classes class-based object model. It uses the mightier prototypical inheritance, which can mimic classes, but is not suited well for it. Everything is an object, and objects [can] inherit from other objects.
A constructor is just a function that assigns properties to newly created objects. The object (created by a call with the new keyword) can be referenced trough the this keyword (which is local to the function).
A method also is just a function which is called on an object - again with this pointing to the object. At least when that function is invoked as a property of the object, using a member operator (dot, brackets). This causes lots of confusion to newbies, because if you pass around that function (e.g. to an event listener) it is "detached" from the object it was accessed on.
Now where is the inheritance? Instances of a "class" inherit from the same prototype object. Methods are defined as function properties on that object (instead of one function for each instance), the instance on which you call them just inherits that property.
Example:
function Foo() {
this.bar = "foo"; // creating a property on the instance
}
Foo.prototype.foo = 0; // of course you also can define other values to inherit
Foo.prototype.getBar = function() {
// quite useless
return this.bar;
}
var foo = new Foo; // creates an object which inherits from Foo.prototype,
// applies the Foo constructor on it and assigns it to the var
foo.getBar(); // "foo" - the inherited function is applied on the object and
// returns its "bar" property
foo.bar; // "foo" - we could have done this easier.
foo[foo.bar]; // 0 - access the "foo" property, which is inherited
foo.foo = 1; // and now overwrite it by creating an own property of foo
foo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that
(new Foo).foo; // is still 0
So, we did only use properties of that object and are happy with it. But all of them are "public", and can be overwritten/changed/deleted! If that doesn't matter you, you're lucky. You can indicate "privateness" of properties by prefixing their names with underscores, but that's only a hint to other developers and may not be obeyed (especially in error).
So, clever minds have found a solution that uses the constructor function as a closure, allowing the creating of private "attributes". Every execution of a javascript function creates a new variable environment for local variables, which may get garbage collected once the execution has finished. Every function that is declared inside that scope also has access to these variables, and as long as those functions could be called (e.g. by an event listener) the environment must persist. So, by exporting locally defined functions from your constructor you preserve that variable environment with local variables that can only be accessed by these functions.
Let's see it in action:
function Foo() {
var bar = "foo"; // a local variable
this.getBar = function getter() {
return bar; // accesses the local variable
}; // the assignment to a property makes it available to outside
}
var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototype
foo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor
This getter function, which is defined inside the constructor, is now called a "privileged method" as it has access to the "private" (local) "attributes" (variables). The value of bar will never change. You also could declare a setter function for it, of course, and with that you might add some validation etc.
Notice that the methods on the prototype object do not have access to the local variables of the constructor, yet they might use the privileged methods. Let's add one:
Foo.prototype.getFooBar = function() {
return this.getBar() + "bar"; // access the "getBar" function on "this" instance
}
// the inheritance is dynamic, so we can use it on our existing foo object
foo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix
So, you can combine both approaches. Notice that the privileged methods need more memory, as you create distinct function objects with different scope chains (yet the same code). If you are going to create incredibly huge amounts of instances, you should define methods only on the prototype.
It gets even a little more complicated when you are setting up inheritance from one "class" to another - basically you have to make the child prototype object inherit from the parent one, and apply the parent constructor on child instances to create the "private attributes". Have a look at Correct javascript inheritance, Private variables in inherited prototypes, Define Private field Members and Inheritance in JAVASCRIPT module pattern and How to implement inheritance in JS Revealing prototype pattern?
Explicitly saying this.foo means (as you've understood well) that you're interested about the property foo of the current object referenced by this. So if you use: this.foo = 'bar'; you're going to set the property foo of the current object referenced by this equals to bar.
The this keyword in JavaScript doesn't always mean the same thing like in C++. Here I can give you an example:
function Person(name) {
this.name = name;
console.log(this); //Developer {language: "js", name: "foo"} if called by Developer
}
function Developer(name, language) {
this.language = language;
Person.call(this, name);
}
var dev = new Developer('foo', 'js');
In the example above we're calling the function Person with the context of the function Developer so this is referencing to the object which will be created by Developer. As you might see from the console.log result this is comes from Developer. With the first argument of the method call we specify the context with which the function will be called.
If you don't use this simply the property you've created will be a local variable. As you might know JavaScript have functional scope so that's why the variable will be local, visible only for the function where it's declared (and of course all it's child functions which are declared inside the parent). Here is an example:
function foo() {
var bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(f.getBar()); //'foobar'
This is true when you use the var keyword. This means that you're defining bar as local variable if you forget var unfortunately bar will became global.
function foo() {
bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(window.bar); //'foobar'
Exactly the local scope can help you to achieve privacy and encapsulation which are one of the greatest benefits of OOP.
Real world example:
function ShoppingCart() {
var items = [];
this.getPrice = function () {
var total = 0;
for (var i = 0; i < items.length; i += 1) {
total += items[i].price;
}
return total;
}
this.addItem = function (item) {
items.push(item);
}
this.checkOut = function () {
var serializedItems = JSON.strigify(items);
//send request to the server...
}
}
var cart = new ShoppingCart();
cart.addItem({ price: 10, type: 'T-shirt' });
cart.addItem({ price: 20, type: 'Pants' });
console.log(cart.getPrice()); //30
One more example of the benefits of the JavaScript scope is the Module Pattern.
In Module Pattern you can simulate privacy using the local functional scope of JavaScript. With this approach you can have both private properties and methods. Here is an example:
var module = (function {
var privateProperty = 42;
function privateMethod() {
console.log('I\'m private');
}
return {
publicMethod: function () {
console.log('I\'m public!');
console.log('I\'ll call a private method!');
privateMethod();
},
publicProperty: 1.68,
getPrivateProperty: function () {
return privateProperty;
},
usePublicProperty: function () {
console.log('I\'ll get a public property...' + this.publicProperty);
}
}
}());
module.privateMethod(); //TypeError
module.publicProperty(); //1.68
module.usePublicProperty(); //I'll get a public property...1.68
module.getPrivateProperty(); //42
module.publicMethod();
/*
* I'm public!
* I'll call a private method!
* I'm private
*/
There's a little strange syntax with the parentless wrapping the anonymous functions but forget it for the moment (it's just executing the function after it's being initialized). The functionality can be saw from the example of usage but the benefits are connected mainly of providing a simple public interface which does not engages you with all implementation details. For more detailed explanation of the pattern you can see the link I've put above.
I hope that with this :-) information I helped you to understand few basic topics of JavaScript.
function Foo() {
this.bar = 0;
this.getBar = function () { return this.bar };
}
When you call the function above with the new keyword - like this...
var foo = new Foo();
... - a few things happen:
1) an object is created
2) the function is executed with the this keyword referencing that object.
3) that object is returned.
foo, then, becomes this object:
{
bar: 0,
getBar: function () { return this.bar; }
};
Why not, then, just do this:
var foo = {
bar: 0,
getBar: function () { return this.bar; }
};
You would, if it's just that one simple object.
But creating an object with a constructor (that's how it's called) gives us a big advantage in creating multiple of the "same" objects.
See, in javascript, all functions are created with a prototype property [an object], and all objects created with that function (by calling it with the new keyword) are linked to that prototype object. This is why it's so cool - you can store all common methods (and properties, if you wanted to) in the prototype object, and save a lot of memory. This is how it works:
function Foo( bar, bob ) {
this.bar = bar;
this.bob = bob;
}
Foo.prototype.calculate = function () {
// 'this' points not to the 'prototype' object
// as you could've expect, but to the objects
// created by calling Foo with the new keyword.
// This is what makes it work.
return this.bar - this.bob;
};
var foo1 = new Foo(9, 5);
var foo2 = new Foo(13, 3);
var result1 = foo1.calculate();
var result2 = foo2.calculate();
console.log(result1); //logs 4
console.log(result2); //logs 10
That's it!
To get closer to OOP in JavaScript, you might want to take a look into a Module design pattern (for instance, described here).
Based on the closure effect, this pattern allows emulating private properties in your objects.
With 'private' properties you can reference them directly by its identifier (i.e., no this keyword as in constructors).
But anyway, closures and design patterns in JS - an advanced topic. So, get familiar with basics (also explained in the book mentioned before).
In javascript this always refers to the owner object of the function. For example, if you define your function foo() in a page, then owner is the javascript object windows; or if you define the foo() on html element <body>, then the owner is the html element body; and likewise if you define the function onclick of element <a>, then the owner is the anchor.
In your case, you are assigning a property bar to the 'owner' object at the begining and trying to return the local variable bar.
Since you never defined any local varialbe bar, it is giving you as bar is undefined.
Ideally your code should have defined the variable as var bar; if you want to return the value zero.
this is like a public access modifier of objects(variables or functions), while var is the private access modifier
Example
var x = {};
x.hello = function(){
var k = 'Hello World';
this.m = 'Hello JavaScript';
}
var t = new x.hello();
console.log(t.k); //undefined
console.log(t.m); //Hello JavaScript

Call/Bind/Apply vs prototype

In the following code:
function User(name) {
this.name = name;
}
var user = new User('Jason Bourne');
User.prototype.sayHi = function() {
return 'Hi ' + this.name;
};
var sayHello = function() {
return 'Hello ' + this.name;
};
Both functions will give me the same result if I bind the object to sayHello (sayHello.bind(user)) or if I use user.sayHi();
So my question is, is there a reason to use one method over the other? I thought I've read somewhere that creating things on prototype is discouraged, if so why?
CORRECTION:
I erroneously wrote Object.prototype.. instead of specifying (Object I create).prototype..
The reason you don't want to use Object.prototype.sayHi = function(){} is that once you do, everything that has Object in its prototype chain will be able to use sayHi. That's the core of prototypical inheritance.
It's OK to add things to the prototype of objects that you create (and it's just considered bad practice to add to Object.prototype). Just understand that when you do, anything in your objects prototype chain will be able to use that function.
function sayHello() {
console.log("hello");
}
// Bad
Object.prototype.hello = sayHello;
Date.hello(); // Prints hello
Call, Apply, and Bind are actually slightly different from adding to prototype and Bind is also different from Call and Apply as well.
Call and Apply
Function.call() and Function.apply() use whatever function you are calling or applying at the moment of the call or apply.
For example, if we wanted to use the forEach() method on a NodeList
var els = document.querySelectorAll("div");
Array.prototype.forEach.call(els, function(el){
el.classList.add("someClass");
The big difference between call and apply is that call takes a variadic argument and apply takes an Array.
function say() {
console.log(arguments);
}
say.call(this, "a", "b");
say.apply(this, ["a", "b"]);
Bind
Using Function.bind() is actually a different thing though. Bind lets you create a context binding where you can call a function from a specific context when you want.
function honk() {
console.log(this.sound);
}
function Car() {
this.sound = "honk";
}
function Van(){
this.sound = "beep";
}
var c = new Car();
var v = new Van();
var ftorCar = honk.bind(c);
var ftorVan = honk.bind(v);
ftorCar(); // prints honk
ftorVan(); // prints beep
You can now pass ftorCar around and call it when you want to and it will have the correct scope "binding".
It's very bad practice to modify the Object.prototype because every object inherits from it, so then every object created now will have a method called sayHi, even objects which do not have the property name.
If you were to create your own class say, it is acceptable to add the sayHi method to the prototype list because then only instances of the type will have that method:
function Person(name){
this.name = name;
}
Person.prototype.sayHi = function() { return 'Hi ' + this.name; }
As for picking one way or another, I would say it's preference mostly. I tend to use prototypes for objects that I create and functions using those prototypes in an internal scope.

What does "this" refer to in JavaScript Parasitic Inheritance?

After years of creating applications using prototypal inheritance in JavaScript, I've started to explore using parasitic inheritance. Despite its primary pitfall - at least to me - of potentially creating several copies of methods in memory as you create an object hierarchy, I'm finding that it really resonates with me with its simplicity and the fact that "new" is rendered unnecessary. However, I'm stuck on what happens with "this." Most of the examples I've seen online only scratch the surface showing how to implement parasitic inheritance like so:
function foo() {
return {
method1 : function() {...}
}
}
function bar() {
var that = foo();
that.method2 = function() {
//is "this" pointing to bar()?
}
return that;
}
As I asked in the comment in the bar() object, does "this" refer to bar() or is the scope of this relegated to method2?
Thanks!
The quick test indicates that this refers correctly to the object returned by bar:
function foo() {
return {
method1 : function() { return "spam" }
}
}
function bar() {
var that = foo();
that.method2 = function() {
return this.method1();
}
return that;
}
var b = bar();
b.method2(); // "spam"
The this context variable in your method2() will be bound to the object, which gets returned from foo() pseudo constructor function. Every function (context) has a bound this, the value from the context variable, depends on the invocation from the method itself.
For instance, calling a function as property from an object (like you do there) will set the this variable to exactly that object. When you just call a function right away, its this is bound to the global object in ES3 and its null in ES5.
There are other methods and keywords which can change the value from this. Like new, .bind(), .call() and .apply(). But again, in your particular snippet here, this will be bound to the object which is stored in that.

improve javascript prototypal inheritance

I'm using a classical javascript prototypal inheritance, like this:
function Foo() {}
Naknek.prototype = {
//Do something
};
var Foo = window.Foo = new Foo();
I want to know how I can improve this and why I can't use this model:
var Foo = window.Foo = new function() {
};
Foo.prototype = {
//Do something
};
Why this code doesn't work? In my head this is more logical than the classical prototypal inheritance.
Your var Foo = window.Foo = new Foo(); example is...odd. First you declare a function Foo, then you assign something to its prototype (I assume you meant to replace Nannak with Foo in your second line), and then you overwrite the reference to the function by assigning to it.
Standard Javascript prototypical inheritance looks like this:
// Create a constructor `Foo`
function Foo() {
}
// Give the prototype for `Foo` objects a function bound to the
// property `bar`
Foo.prototype.bar = function() {
}
// Only do this bit if you're doing this within a function and you want
// to make `Foo` available as a property of `window` (e.g., effectively
// a global variable. If this code is already at global scope, there's
// no need to do this.
window.Foo = Foo;
Here's how you'd use Foo:
// Create a `Foo` and use its `bar`
var f = new Foo();
f.bar();
A couple of other notes:
Never use new function() { ... } unless you really, really know what you're doing. It creates an object initialized by the function, it does not create a new function. There's almost never any need for the similar (but totally different) new Function(...), either, again except for some advanced edge cases.
The function bound to bar in my example above is anonymous (the property it's bound to has a name, but the function does not). I'm not a fan of anonymous functions, but I didn't want to clutter the example above. More here.
If you use var at global scope (it wasn't clear from your question whether you were), it creates a property on the window object. You'd only need to do var Foo = window.Foo = ... if you're within a function and want to both create a propety of window and create a local variable called Foo. (Which maybe you meant to do! :-) )
The Foo.prototype = { .. }; way of assigning prototypical properties works, but it's not generally a good idea (again, unless you're pretty up-to-speed on this stuff). When you do that, you're completely replacing the prototype object used when you call the function via new, whereas if you just add properties to it (Foo.prototype.bar = ...), you're just augmenting the prototype, not replacing it. Replacing the prototype is perfectly valid, but there are some non-obvious things that can happen if you're unwary. :-)
You are using the new operator on the function expression, that causes a newly created object to be assigned to window.Foo.
That new object is not a function, therefore it doesn't have a prototype property and it cannot be invoked.
"doesn't work" is vague, but I think the root cause is new function() { (new doesn't belong here)
You probably want:
var Foo = window.Foo = function() {
};
Foo.prototype = {
bar: 'baz'
};
alert(new Foo().bar); // baz

this inside function

My question is:
function Foo()
{
this.foo = "bar"; // <- What is "this" here?
}
From what I can tell it depends on how Foo is used, i.e. as a constructor or as a function. What can this be in different circumstances?
The this keyword refers to the object the function belongs to, or the window object if the function belongs to no object.
It's used in OOP code, to refer to the class/object the function belongs to
For example:
function foo() {
this.value = 'Hello, world';
this.bar = function() {
alert(this.value);
}
}
var inst = new foo();
inst.bar();
This alerts: Hello, world
You can manipulate which object this refers to by using the apply() or call() functions. (A very very handy feature at times)
var bar1 = new function() {
this.value = '#1';
}
var bar2 = new function() {
this.value = '#2';
}
function foo() {
alert(this.value);
}
foo.call(bar1); // Output: #1
foo.apply(bar2, []); // Output: #2
Read what Douglas Crockford has to say on the matter, to quote him from A Survey of the JavaScript Programming Language:
A function is an object. It can contain members just as other objects. This allows a function to contain its own data tables. It also allows an object to act as a class, containing a constructor and a set of related methods.
A function can be a member of an object. When a function is a member of an object, it is called a method. There is a special variable, called this that is set to the object when a method of the object is called.
For example, in the expression foo.bar(), the this variable is set to the object foo as a sort of extra argument for the function bar. The function bar can then refer to this to access the object of interest.
In a deeper expression like do.re.mi.fa(), the this variable is set to the object do.re.mi, not to the object do. In a simple function call, this is set to the Global Object (aka window), which is not very useful. The correct behavior should have been to preserve the current value of this, particularly when calling inner functions.
Also 'this' can change depending on how your function is invoked, read on apply function and call function.
I would recommend that you spend time learning form one of JavaScript's greatest minds in his (free) presentations, linked from here.
In JavaScript, the convention (and this is only a convention) is that any function that begins with a capital letter is to be used as a constructor. Then, one would call
var foo = new Foo() and this would refer to the newly created object that is about to be referenced by foo.
Of course, there is nothing stopping you from calling Foo() on its own, in which case this would then refer to the object from which the function was called. To avoid confusion, that is not recommended.
Its depends on how that function is used, there are two basic types in which we can use functions
Function
Function as an Object, by using new keyword
will see one by one
1.Function
var example = function () {
console.log(this);
};
example();
Output : window
Here 'this' keyword points to window object.
By default, this should always be the window Object, which refers to the root - the global scope. So when we console.log(this); from our function, as it’s invoked by the window (simply just called), we should expect the this value to be our window Object:
2.Function as an Object
var example = function () {
console.log(this);
};
var obj = new example();
Output : example {}
Here 'this' keyword points to newly created example object.
In NodeJS there is some interesting behaviour:
function foo() {
this.name = 'bar' // <- What is "this" here?
}
foo() // <- TypeError: Cannot set property 'name' of undefined
But using an arrow function:
const bar = () => {
this.name = 'foo'
console.log(this)
}
bar() // <- { name: 'foo' }
I was always under the impression that a traditional function literal had its own context but not arrow functions, this seems to contradict my understanding.
Given this behaviour the code by the OP would not work...
In JavaScript everything is object even functions. When you say this.foo in following code
function Foo()
{
this.foo = "bar"; // <- What is "this" here?
}
foo becomes member variable of Foo object

Categories