JavaScript return method - javascript

I'am new in javascript.
I can't understand why the function returns T1 object (not just string 'hi') in the following example.
function T1(){
return 'hi';
}
function T(){
return new T1();
}
T();
output: T1
And returns function in the following example
function T1(){
return function(){ return 'hi'; }
}
function T(){
return new T1();
}
T();
output: function (){ return 'hi' }
Why does the first example returns an object (not the string "hi", what is expected to happen) and the second returns the function body that is returned from the first function (not the expected object)?
Please explain this result. Thank you)

The new operator returns the object created by the operator unless the constructor function returns a different object. Any non-object return value of the constructor function is ignored, which is why when you return hi you don't see this.
Section 13.2.2 ("[[Construct]]") of the specification, which is referenced by Section 11.2.2 ("The new operator").

The new keyword. That makes an object.
function T1(){
return 'hi';
}
function T(){
return T1();
}
T(); // 'hi'
JavaScript objects should be like this:
function T1(){
this.test = function(){
return 'hi';
};
}
function T(){
return new T1();
}
var test = T(); // T1 object
test.test(); // 'hi'

In your code:
> function T1() {
> return 'hi';
> }
A function called as a constructor will always return an object, it won't return a string. So when called simply as a function, T1 will return the string 'hi', but when called as a constructor, it iwll return a new T1 instance. Since that instance isn't assigned any properties, nor does T1.prototype seem to have any, it will be almost indistinguishable from an object created using new Object().
It will be an instanceof T1 and its constructor property will reference T1.
> function T() {
> return new T1();
> }
By convention, only constructors start with a capital letter (except for constants, which might be all capitals).
> T();
The T function simply returns a new T1 object, which is not assigned to anything so can't be referenced or called, so it's immediately available for garbage collection. It has not special methods or properties.
var t = T(); // returns a new T1 instance
t(); // throws an error since t is a plain object,
// not a function and so can't be called.
Edit
Since the question was changed:
function T1() {
return function(){ return 'hi'; }
}
In this case, when T1 is called as a constructor, the return statement returns a function, which is an Object (all functions are objects), so that is what is returned.

The function is returned in the second example because you returned an anonimous function on T1() and so, you can execute it placing a pair of parentesis () in front of if:
function T1(){
return function(){ return 'hi'; }
}
function T(){
return new T1();
}
T()(); // hi
// or
var T2 = T();
T2(); // hi
This is not a bug, its a powerfull feature from JS.
Just remember of "Spiderman" frase:
With great powers cames great responsabilities.
Edit:
Now I see the real question: Why does the first example returns an object (not the string "hi", what is expected to happen) and the second returns the function body that is returned from the first function (not the expected object)?
This seems a bug to me, but maybe by design, since functions and objects returned can be used and a workaroud with a parameter is easy to do.

Related

Javascript Function Strange Behavior [duplicate]

What are the exact circumstances for which a return statement in Javascript can return a value other than this when a constructor is invoked using the new keyword?
Example:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if something is a non-function primitive, this will be returned. Otherwise something is returned. Is this correct?
In other words, what values can something take to cause (new Foo () instanceof Foo) === false?
The exact condition is described on the [[Construct]] internal property, which is used by the new operator:
From the ECMA-262 3rd. Edition Specification:
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is
called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to "Object".
Get the value of the prototype property of F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as
described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and
providing the argument list passed into [[Construct]] as the
argument values.
If Type(Result(6)) is
Object then return Result(6).
Return Result(1).
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6) (the value returned from the F constructor
function) is not an Object.
Concrete examples
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5) from a constructor, but not the literal 5 (which is ignored and this is returned instead).
As a side note, the return value or this is just part of the equation.
For example, consider this:
function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
As you can see, .valueOf() is internally used and can be exploited for fun and profit. You can even create side effects, for example:
function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
I can imagine this must have some sort of practical application. And it doesn't have to be explicitly a Number either, if you add .valueOf to any object it can behave as a number:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
Trying to put a few points in simpler words.
In javascript, when you use a new keyword on a function and if,
function does not return anything, it will return an intended object
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
function returns any truthy complex object [object, array, function etc], that complex object takes priority and user variable will hold the returned complex object
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function returns any literal, constructor takes priority and it will return an intended object
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
When you are using the new keyword, an object is created. Then the function is called to initialise the object.
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.

Working of Date in Javascript

I recently learned that we can't access inner function directly. We need to make the object of the function to do that. However it looks different to me in Date function since we can access inner functions like Date.now().typeof Date returns "function" and not "Object".
What am I missing here?
You can make a such thing. Here b function is a function of the A.
Typeof A will return function. But in Javascript functions are also objects. So you can add properties and functions(methods) to the function object itself.
function A(){
}
A.b = function(){
console.log('B');
}
A.b();
But if you mean inner function to this
function A(){
function b(){
console.log('b') ;
}
}
You can't access the inner b function outside the A .
One case to access the inner function outside the A, you need to assign the function to the this, which is called method, then create an object of A and use that method.
function A(){
this.b = function (){
console.log('b');
};
}
let a = new A();
a.b();
Actually, Date is the constructor of the Object Date,
so it is a common sense that you use new Date() to get access into these 'inner functions' you referred in your question:
type of Date // function
type of Date() // string, shorthand of new Date().toString()
type of new Date() // object
The inner function mostly is a constructor Function.
e.g:
function MyDate () {
}
MyDate.prototype.getDate = function () {
console.log('getDate')
}
MyDate.getDate() // getDate

Any difference between explicit and implicit return in javascript function?

Is there any difference when I explicitly return from a function vs. implicitly return?
Here's the code that puzzles me ATM:
function ReturnConstructor(arg){
// Private variable.
var privateVar = "can't touch this, return ctor.";
// This is what is being exposed to the outside as the return object
return {
print: function() {
console.log("ReturnConstructor: arg was: %s", arg);
}
};
}
function NormalConstructor(arg){
// Private variable.
var privateVar = "can't touch this, normal ctor";
// This is what is being exposed to the outside as "public"
this.print = function() {
console.log("NormalConstructor: arg was: %s", arg);
};
}
var ret = new ReturnConstructor("calling return");
var nor = new NormalConstructor("calling normal");
Both objects ('ret' & 'nor') seem the same to me, and I'm wondering if it's only personal preference of whomever wrote whichever article I've read so far, or if there's any hidden traps there.
When you use new, there's an implicit value. When you don't use new, there isn't.
When a function called with new returns an object, then that's the value of the new expression. When it returns something else, that return value is ignored and the object implicitly constructed is the value of the expression.
So, yes, there can be a difference.
Implicit return only happens for single statement arrow functions, except When arrow function is declared with {}, even if it’s a single statement, implicit return does not happen:
link

Javascript: Function - Return an Object will invalid this.variable

I m using javascript. Declaring a instance variable "this.variable" will work until my function will return an object. Return of an String, Number doesnt affect it. In the case of returning an object the instance variable doesnt work anymore and become "undefined". Please can you help me! (Look for a sample at http://jsfiddle.net/woko/vE4rq/2/ tested under recent versions of firefox & chrome )
function Funct() {
this.varfunc = "this ist a instance";
return false;
}
var f = new Funct();
console.log(f.varfunc);
function FunctReturnobj() {
this.varfunc = "this ist a instance + return an object";
return {};
}
var fr = new FunctReturnobj();
console.log(fr.varfunc)
this in the scope of a function is DOMWindow.
this in the scope of an object is the object.
You're using constructors in a wrong way. Constructors shouldn't return anything themselves. You can use the prototype property to declare "class"/object methods or you can set them in the constructor like you already do:
function Constructor(value) {
this.variable = value;
}
var obj = new Constructor('test');
obj.variable; // -> Returns 'test';
Same way you can declare methods of you object:
function Constructor(value) {
this.variable = value;
this.say = function(something) {
return "I say: " + something;
};
}
Or the prototype way:
function Constructor(value) {
this.variable = value;
}
Constructor.prototype.say = function(something) {
return "I say: " + something;
};
Of course this a generic and kinda bad example, but you probably get the point :)
The new operator will create a new object and apply the function on it - this in the function scope refers to that object.
But when the function is called without new, or contains a return statement, it won't be executed as a "constructor". this will point to the execution context, usually the window object.

What values can a constructor return to avoid returning this?

What are the exact circumstances for which a return statement in Javascript can return a value other than this when a constructor is invoked using the new keyword?
Example:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if something is a non-function primitive, this will be returned. Otherwise something is returned. Is this correct?
In other words, what values can something take to cause (new Foo () instanceof Foo) === false?
The exact condition is described on the [[Construct]] internal property, which is used by the new operator:
From the ECMA-262 3rd. Edition Specification:
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is
called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to "Object".
Get the value of the prototype property of F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as
described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and
providing the argument list passed into [[Construct]] as the
argument values.
If Type(Result(6)) is
Object then return Result(6).
Return Result(1).
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6) (the value returned from the F constructor
function) is not an Object.
Concrete examples
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5) from a constructor, but not the literal 5 (which is ignored and this is returned instead).
As a side note, the return value or this is just part of the equation.
For example, consider this:
function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
As you can see, .valueOf() is internally used and can be exploited for fun and profit. You can even create side effects, for example:
function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
I can imagine this must have some sort of practical application. And it doesn't have to be explicitly a Number either, if you add .valueOf to any object it can behave as a number:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
Trying to put a few points in simpler words.
In javascript, when you use a new keyword on a function and if,
function does not return anything, it will return an intended object
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
function returns any truthy complex object [object, array, function etc], that complex object takes priority and user variable will hold the returned complex object
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function returns any literal, constructor takes priority and it will return an intended object
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
When you are using the new keyword, an object is created. Then the function is called to initialise the object.
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.

Categories

Resources