use strict not allow use of this in node.js - javascript

After using 'use strict' statement in my js file it does not allow me to use javascript this after ist level
'use strict'
module.exports = {
a: function() {
var self = this //works fine upto this level
var name = 'atul';
function b() {
this.name = name; //gives me error as can not set property name of undefined
}
}
}

this and Javascript:
this references to the global object by default. ("window" on browsers)
this references to the calling object example:
var x = {name: "x", alphabet: function(){return this;}};
x.alphabet(); // in this line, x is the calling object
this will show you the object itself.
So when you do:
...
a: function() {
var self = this //works fine upto this level
var name = 'atul';
function b() {
this.name = name; //use strict is trying to tell you something
}// you won't have a calling object for this function.
}
...
use-strict says: this function is not even an object property or method. Since it's not a method it's this will point to the global object and lead to error prone development.
If you wish to use your code in this particular way.
module.exports = {
a: {
name: 'atul';
b: function (name) {
this.name = name; // now you have a as the property which can be called by an object a.
//To be used as OBJECT.a.b();
}
};
};

this is undefined as it is not autoboxed to an object in strict mode.
First, the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a normal function, this is always an object: either the provided object if called with an object-valued this; the value, boxed, if called with a Boolean, string, or number this; or the global object if called with an undefined or null this. (Use call, apply, or bind to specify a particular this.) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard, because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be undefined
Read more at MDN

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

In JavaScript, why non-existent "window" property values differ in these two situations?

I have a piece of JavaScript code:
var o = {
name: "aaaa",
f: function () {
console.log(this);
console.log(this.name);
}
};
var m1 = o.f;
m1();
console.log(window.non_existent_property);
As I understand, the property name shouldn't matter too much. If I change the name of property name of object o to something like a everywhere, I should have the same result. However, this is not the case. See below image. I'm running the code on FireFox 75.0. Could anyone explain what is happening here please?
The issue is not with the property of o in the object - the property name there is actually completely irrelevant, because you're losing the calling context when you assign the function to a standalone variable:
var m1 = o.f;
m1();
The above code means that m1 is called with no calling context, which means that this inside the m1 function will either be the global object (in sloppy mode), or undefined (in strict mode).
Since you're in sloppy mode, this.name references window.name, which is a reserved property that always exists on window and must always be a string. It defaults to the empty string.
Here's another snippet demonstrating the same sort of issue:
var foo = 'foo';
var o = {
f: function () {
console.log(this.foo);
}
};
var m1 = o.f;
m1();
foo is a property of the window, since a global variable named foo was declared with var, so this.foo references window.foo.

Comparison of the two situations when the constructor is called without the new keyword

function Person(name, age, gender) {
this.name = name; // run
}
function PersonSafe(name) {
if (!(this instanceof arguments.callee))
return new PersonSafe(name)
this.name = name; // run
}
var qux = Person('qux');
console.log('Person qux: ', qux);
console.log('[[global]] name: ', name);
var quxSafe = PersonSafe('qux');
console.log('PersonSafe qux: ', quxSafe);
A comparison of the two situations when the constructor is called without the new keyword.
I don't know why the results of running the two codes are different.
The body ofPerson()andPersonSafe()functions are different, but the line (this.name = name;) thatqux and quxSafe will execute is the same.
So... Why are the results different?
When you call a function as a constructor (here, Person), an object is created (an empty object whose internal prototype is the constructor function's prototype - Person.prototype here), and that object that was just created is what the this value will point to inside the function. That object will also be implicitly returned at the end of the constructor.
In contrast, when you don't use new, no such object is created; you're just calling an ordinary function, and the this value inside it will depend on the calling context of the function. Here, because there's no calling context (the function being called is not part of an object), the this inside the function will either be the global object (in the case of sloppy mode), or undefined (in the case of strict mode).
So var qux = Person('qux'); runs this.name = name, where this is the global object.
With PersonSafe, you're checking that the this is an instance of the constructor (that the this has an internal prototype of the constructor's prototype) - if called without new, that test will fail, since this will be either the global object or undefined.
Note that arguments.callee is forbidden in strict mode, and strict mode should nearly always be used. Consider replacing with new.target instead:
function PersonSafe(name) {
if(!(new.target))
return new PersonSafe(name)
this.name = name; // run
}
var quxSafe = PersonSafe('qux');
console.log('PersonSafe qux: ',quxSafe);
The main reason why this is different is caused by "new" keyword which means that function will be treated as object and it will get proto property assigned.
Also this variable will be pointed to newly created object.
Here is good description: What is the 'new' keyword in JavaScript?

Calling a constructor function | why does "this" keyword return undefined?

I'm playing around with objects and constructors and am curious why I can't execute: person(5,10). The parameters are passed to the person function but then the variable assignment disappears and I get the "cannot set property "age" of undefined" error in chrome.
"use strict"
function person(age, height){
this.age = age;
this.height = height;
this.calculate = function(){
var newHeight = this.height * 2;
console.log(newHeight);
}
}
person(5,10);
The confusion comes because a function can be used as a callable function and an object constructor both.
Good practice is to not mix up both forms, meaning a constructor function should not be used as a callable function.
In general constructor function has first letter capitalized (just by convention to give a hint to the reader of the code).
Object based languages in general implicitly provide the reference to the object on which a method is called. In Javascript this reference is "this" keyword inside the function.
Consider the following code.
var obj = {
sum: 0,
add: function(increment) {
this.sum += increment;
return this.sum;
}
};
When we call obj.add(2), interpreter or compiler in any other object based language will do an internal calling of method add as following
add(arguments..., [this=obj]) {
//this is the obj reference inside the method
}
add(arguments, obj);
Above is just a pseudo code, last parameter is hidden from us and we don't need to pass it explicitly, this parameter is the reference to the actual object on which the add() method was invoked and is available via "this" keyworkd.
In general when we declare a function outside an Object scope, it becomes method (Edited** if not nested in another function) of the global object ( normally window object). So it's invokation will pass global object as the "this" reference. In strict mode default global object is undefined and any operations that have to be done on the window or global object are to be done explicitly. So that we do not modify the global object inadvertently.
When we call a function as a constructor like below
var p1 = new Person();
Interpreter will execute a code similar to
var newObj = new Object();
Person(arguments..., [this=newObj]) {
//this is the newObj reference inside the method
return this;
}
Person(arugments..., newObj);
I hope it's a bit clearer now.
I get the "cannot set property "age" of undefined" error in chrome.
When you call a function in strict mode, this is undefined. It seems you want to call the function as constructor, with new:
new person(5, 10)
Learn more about constructors.
Note: The convention is to capitalize the name of constructor functions.

How does Javascript evaluate "this"?

I am trying to understand some basic javascript .
I have the following snippet. We have the name variable which in both cases are referenced over getName Method.
First alert outputs HocusPocus, while the second one outputs GeorgeThomas. But I do not understand how this refers to name in this case
var name = 'Gerorge Thomas';
var obj = {
name: 'Cinderella',
value: {
name: 'HocusPocus',
getName: function() {
return this.name;
}
}
};
alert( obj.value.getName() );
var testing = obj.value.getName;
alert(testing());
To understand this issue, you have to understand how Javascript sets the value of this in a function call.
There's a summary of all the methods here: When you pass 'this' as an argument
For your particular case, when you do this:
var testing = obj.value.getName;
You now have a reference to the getName function. You no longer have any connection at all to obj.value. So, test() just calls getName as an ordinary function. In Javascript when an ordinary function call is made, then the value of this will be either the global object (window in a browser) or in strict mode, it will be undefined.
In your case, this becomes the window object so this.name is window.name which points to the global variable name and thus you get the result 'Gerorge Thomas'.
In fact, if you run your code in strict mode, it will cause an error which is, in fact, one of the benefits of strict mode that it points out accidental errors like this.
On the other hand, if you execute a function with the form of obj.method(), then this is set to be obj. So, when you do:
obj.value.getName()
that is equivalent to:
var o = obj.value;
o.getName()
which is the obj.method() form of calling a function which will set the this pointer to be the object, which in this case is obj.value.
It is possible to work around this issue in a couple of ways. Here's an example of working around it using .bind().
var name = 'Gerorge Thomas';
var obj = {
name: 'Cinderella',
value: {
name: 'HocusPocus',
getName: function() {
return this.name;
}
}
};
document.write( obj.value.getName() + "<br>");
var testing = obj.value.getName.bind(obj.value);
document.write(testing());
Well it only needs some reflection, let's analyse it:
In the first alert we are calling the getName() method of the
obj.value object so it returns obj.value.name which is
"HocusPocus".
alert( obj.value.getName() ); we call this.name where this refers to obj.value so name is HocusPocus
But in the second alert we are creating a new function testing()
with the body of the getName() method, so it will be attached to
the global window object and if we call it we will get the global
name value wich is 'Gerorge Thomas'.
alert(testing()); we are dealing with this.name where this refers to the global scope so name is 'Cinderella'.
First, you're calling a method from inside the obj object. The 2nd time, you're making a copy of the function (not really, it's just a reference) in the global scope. So you could also write window.testing() for the 2nd call. I think that makes it clear.

Categories