get function execution context - javascript

I have a function foo:
function foo() {
return 'foo';
}
While foo got executed is there a way to know if foo was called inside object declaration ? I want to distinguish these two cases:
var bar = {
prop1: foo()
}
var var1 = foo();

Here's one approach demonstrating the suggestions in the comments and assuming you'd rather call bar.prop1 instead of bar.prop1().
function foo (ctx) {
console.log(ctx == window)
return 'foo'
}
class Bar {
get prop1() {
return foo(this)
}
}
var var1 = foo(this);
var bar = new Bar();
bar.prop1;

Related

Aspect Oriented Programming without Modification of Original

So, I have seen examples on AOP in Javascript and most of them either are something like this:
var foo = somefunc.after(function() { // after is some function already made
console.log("after!");
});
foo(); // logs "after"
Like this:
var foo = function() {
console.log("something");
};
foo = (function() {
var original = foo;
return function() {
console.log("before!");
original.apply(this, arguments);
}
})();
foo(); // logs "before" then "after"
Or like this:
function Foo() {
console.log("foo");
}
var original = Foo;
Foo = function() {
original();
moreStuff();
}
function moreStuff() {
console.log("hi");
}
Foo();
// logs "foo" then "hi"
But, what want is a way that does not modify the original function and you do not have to set it to a variable. What I am looking where the you can do this:
function foo() {
console.log("foo!");
}
foo.after(function() {
console.log("after");
});
// and then
console.log(foo);
/* and it will log:
*
* function foo() {
* console.log("foo!");
* }
*
* Original function stays the same
*/
foo();
// logs "something" then "before"
Basically, when the person calls the function it uses the modified version, but when a person just receives the value of the function, foo;, it returns the original.
How would one achieve this?

Javascript function returning global assigned to itself, then assigned to something else

var bar = function foo() {
foo = 1;
return foo;
};
bar(); // returns function foo()
Why is this happening? I expect this to return 1.
If you want it to return 1, you need to write it like this:
var bar = function() {
foo = 1;
return foo;
};
LVarayut's answer is actually right, you are writing over foo which is in the global namespace. This version declares a local variable foo.
var bar = function() {
var foo = 1;
return foo;
};
Here is a similar question that describes the same behavior...
Function and variable with the same name
And a linked article that describes what is happening...
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
It's because you have defined foo variable twice, so if you want to return 1, you could change the name of your function to anything else:
var bar = function baz() {
foo = 1;
return foo;
};
bar(); // returns 1
Or you could define a local variable:
var bar = function foo() {
var foo = 1;
return foo;
};
bar(); // returns 1
EDIT:
Here is the answer of your question. The name of a named function expression becomes a local variable and can be only accessed inside the function expression. There is a distinction between the function name and the variable the function is assigned to. The function name cannot be changed, while the variable the function is assigned to can be reassigned.
Read more on MDN.

Change function in function

I have ready code something like this and
I can't change function Foo() because it's alias framework.
function Foo(){
this.prop = {
width: 200
}
this.do = function(s1,s2){
alert(s1+s2);
}
}
I need change do function.
After function Foo() and before var foo1 = new Foo(); foo1.do(1,0); I try write
Foo.do = function(){
alert('changed');
}
I can't change do function. I used defineProperty and even constructor) I haven't prototype.
Full uncorrect demo code
function Foo(){
this.prop = {
width: 200
}
this.do = function(s1,s2){
alert(s1+s2);
}
}
Foo.do = function(){
alert('changed');
}
var foo1 = new Foo();
foo1.do(1,0);
var foo2 = new Foo();
foo2.do(1,1);
var foo3 = new Foo();
foo3.do(1,2);
I can change it for foo1, foo2 and etc. I need cange it ine time.
I'd suggest creating your own constructor that implements Foo.
function Foo() {
this.prop = {
width: 200
}
this.do = function (s1, s2) {
console.log(s1 + s2);
}
}
Foo.prototype.someMethod = function () {};
// can't change any of the above..
function MyFoo() {
Foo.call(this);
this.oldDo = this.do;
this.do = function (s1, s2, s3) {
// do something else!
console.log(s1 + s2 + s3);
}
}
MyFoo.prototype = Object.create(Foo.prototype);
// tests...
var foo = new Foo();
foo.do(2, 2, 2); // 4
console.log(foo.prop.width); // 200
var myFoo = new MyFoo();
myFoo.do(2, 2, 2); //6
console.log(myFoo.prop.width); // 200
Your new constructor only has to override the methods you want to change, the rest will stay the same and the original isn't changed. Notice how instances of MyFoo also have a .prop property even though that was done in Foo's constructor, not MyFoo.
newDo = function(){}; // your new do function
var foo1 = new Foo()'
foo1.do = newDo;
foo1.do(1,0)
and so on. If you can't change the Foo function, and you can't restrict yourself to ES6 or Firefox (they have ways to modify the prototype), then the best option is to overwrite do after creating a new Foo.
This is also a good point to plug learning the module pattern so that you can create your own nested versions of things:
function Foo() {}; //your original foo
(function() {
function Foo() {}; //your new foo with a new do method
// do stuff with the modified do here
})()

How to create a new object from an existing one?

This doesn't work, and I have no idea how to fix it
function bar() {...}
function foo() {
this = new bar();
this.newfunction = function() {...};
this.newvalue = "foobar";
}
var foobar = new foo();
Thanks in advance,
Do not use this to represent another object.
function bar() {...}
function foo() {
var bar = new bar();
bar.newfunction = function() {...};
bar.newvalue = "foobar";
}
var foobar = new foo();
Are you trying to inherit from bar? Then you can borrow its constructor and all its own properties using call (or apply):
function bar() {...}
function foo() {
bar.call(this);
this.newfunction = function() {...};
this.newvalue = "foobar";
}
var foobar = new foo();

How to get 'this' value of caller function?

If I have a function like this:
function foo(_this) {
console.log(_this);
}
function bar() {}
bar.prototype.func = function() {
foo(this);
}
var test = new bar();
test.func();
then the test instance of bar gets logged.
However, for this to work I have to pass the this in the bar.prototype.func function. I was wondering whether it is possible to obtain the same this value without passing this.
I tried using arguments.callee.caller, but this returns the prototype function itself and not the this value inside the prototype function.
Is it possible to log the test instance of bar by only calling foo() in the prototype function?
If the question is 'without passing this (by any means)' then answer is no
value can be passed by alternative methods though. For example using global var (within Bar class) or session or cookies.
function bar() {
var myThis;
function foo() {
console.log(myThis);
}
bar.prototype.func = function() {
myThis = this;
foo();
}
}
var test = new bar();
test.func();
I think calling foo within the context of bar should work:
function foo() {
console.log(this.testVal);
}
function bar() { this.testVal = 'From bar with love'; }
bar.prototype.func = function() {
foo.call(this);
}
var test = new bar();
test.func(); //=> 'From bar with love'
You can do this without changing the external function, but you must change the way you call it.
You can't get the context of the caller, but you can set the this property on a function you call with the method apply or call. See this reference for an explanation on this.
function foo()
{
console.log( this );
}
function bar()
{
bar.prototype.func = function func()
{
foo.apply( this );
};
}
var test = new bar();
test.func();
Usually if this is used, it's in an object oriented context. Trying to call a method of an object with another this might indicate poor design. Explain a bit more what you are trying to achieve for more applicable design patterns.
For an example of a javascript OOP paradigm, check my answer here.
What about this?
"use strict";
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.prototype = o;
bar.prototype.constructor = bar;
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();
Or this:
"use strict";
Function.prototype.extender = function( o ){
if(typeof o == 'object'){
this.prototype = o;
}else if ( typeof o == 'function' ) {
this.prototype = Object.create(o.prototype);
}else{
throw Error('Error while extending '+this.name);
}
this.prototype.constructor = this;
}
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.extender(o);
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();

Categories