What is the purpose of this.apply(obj); when function is invoked. For example this code.
Function.prototype.blio = function (a) {
this.hurka = 'hurka';
var obj = {};
this.apply(obj); // what exactly happens here ?
}
Let's try it out!
function foo() {
console.log(this);
}
foo(); // logs window
console.log(foo.hurka); // undefined
foo.blio(); // logs {}
console.log(foo.hurka); // "hurka"
But wait, foo.blio invoked foo!
Therefore, when invoked as foo.blio()
this in blio is foo
this.apply is equivalent to foo.apply
this inside foo was set to {} through the apply
You can read more on Function.prototype.apply on MDN docs here
Related
I am developing a JavaScript code instrumentation tool.
Given a piece of code, suppose I need to modify it to finish the following task:
Task: Assigning a new property to each function when it is invoked and access the property from within the function body.
And I am only allowed to add new lines of code into the original code. Other changes like deletion are NOT allowed.
Considering the following example
foo();
function foo() { // All functions are assumed to have names
}
I can modify it by adding two lines of code like this (basically I directly assign and access the added property by referring to the function name):
foo.prop = ...; // give foo a new property
foo();
function foo() {
console.log(foo.prop); // access the property
}
However, if there is another function with same name declared inside foo, the above solution does not work. Considering the following example.
foo();
function foo() { // All functions are assumed to have names
function foo() {...}
}
After modification:
foo.prop = ... // give foo a new property
foo();
function foo() {
console.log(foo.prop); // property does not exist!
function foo() {...}
}
Because of function hoisting, the outer foo is overridden by the inner foo, therefore, I cannot access the added property using function name.
Using arguments.callee may also fail in strict mode. So it is not an option for me. Are there any valid methods that can finish this task? Or it is actually impossible to do?
I'm not sure if you're searching for a vulnerability or if this is simply a learning exercise. In any case, you can set it on Object.prototype, and it will be inherited by foo (and all other objects... which include functions). Then you can delete the property when you're done with it:
Object.defineProperty(Object.prototype, 'prop', {
configurable: true,
enumerable: true,
writable: true,
value: 'bar',
});
// invoke
foo(); // "bar"
const obj = {};
console.log('obj', obj.prop); // "obj" "bar"
obj.prop = 'baz';
console.log('obj', obj.prop); // "obj" "baz"
// "undefine" the prop
delete Object.prototype['prop'];
console.log('obj', obj.prop); // "obj" "baz"
// invoke again
foo(); // undefined
function foo() {
console.log(foo.prop);
function foo() {}
}
You could use the bind function here:
function foo() {
console.log("outer", this.prop);
function foo() {
console.log("inner", this.prop)
}
foo();
}
const binded = foo.bind({prop: 2});
binded();
This sets the this object in a function to a specific value. Note that the this object is different in the inner foo function!
Sorry if this isn't clear, but I have to objects A and B. A creates an instance of B. B has a method bar that invokes a callback function. The function passed to B is one of A's methods foo, but foo's this refers to B not A. How do I fix this.
function A(){
this.test=(new B(this.foo));
this.test.bar();
}
A.prototype.foo=function(){
console.log(this instanceof A);//needs to return true
}
function B(fn){
this.fn=fn;
}
B.prototype.bar=function(){
this.fn();
}
var a=new A();
You have a very unusual data structure here. Anyway, you can set the context and args for future invocations of a function using Function.prototype.bind
function A(){
this.test=(new B(this.foo.bind(this)));
this.test.bar();
}
Please be aware that binding creates a new instance of the function, so === will now fail;
function foo() {}
var bar = foo.bind(null),
baz = foo.bind(null);
foo === bar; // false
bar === baz; // false
baz === foo; // false
You are simply passing the function of A's foo to B constructor, you must still bind A's this to foo before to ensure it is called properly.
function A() {
this.test = new B(this.foo.bind(this));
this.test.bar();
}
david sharif made a JS quiz which pretty much looks like-
var foo=1;
function bar(){
return foo;
foo=10;
function foo(){}
var foo =5;
}
typeof bar();//?
In my understanding, functions are hosited first and then variable declared inside. the hosited form of the function would be something like (correct me if i am wrong)-
var foo=1;
function bar(){
function foo(){}
var foo;
return foo;
foo=10;
foo =5;
}
typeof bar();//?
why typeof bar() is function not undefined?
Is this because of, at the time of function execution, it finds the first foo (which is a function) and returns happily without continuing search. Or something else?
Appreciate your time.
I found the answer in David Shariff blog.
"Shamelessly copied from his blog"-
Even though foo is declared twice, we know from the creation stage that functions are created on the activation object before variables, and if the property name already exists on the activation object, we simply bypass the declaration.
Therefore, a reference to function foo() is first created on the activation object, and when we get interpreter gets to var foo, we already see the property name foo exists so the code does nothing and proceeds.
If this sound like greek, read the whole blog
The Function Declaration "shadows" the var statement.
Paste this in to your console:
var foo = function(){}
var foo
typeof foo
This is how the code "looks like" to the Interpreter after compiletime:
var bar = function bar(){
var foo = function foo(){}
foo
return foo;
// never reached
foo = 10;
foo = 5;
}
var foo;
foo = 1
typeof bar();//"function"
Function declarations are evaluated upon entry into the enclosing scope, before any step-by-step code is executed. The function's name (foo) is added to the enclosing scope (technically, the variable object for the execution context the function is defined in).
Example 1
From this example wecan see that even we are declaring foo after the return statement, we can still get foo returned.
function bar() {
return foo;
function foo() {} // this will get initialized before the return statement.
}
console.log(typeof bar()); // this will be function
Example 2
From this example we can see that if we are declaring our variables in a normal way after the return statement, they will not execute(assigned).
Declare function after return.
function bar() {
return foo;
var foo = function() {} // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Declare number after return
function bar() {
return foo;
var foo = 12; // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Example 3
Now let's walk through a messier example line-by-line.
function bar() {
return foo;
function foo() {} // <-- initialize foo as a function
var foo = 11; // <-- this will not get assigned
}
console.log(typeof bar()); // function
I hope the above example will not only answer you question but also give you a better understanding of:
var foo = function() {} vs function foo() {}
In below example about Scope, I dont understand that how could a variable is running as a function? in here var f is running as f(). However, is this a sound method to run f in JavaScript? Why? Is it because var f stored a function?
var myFunction = function() {
var foo = "hello";
var myFn = function() {
console.log( foo );
};
foo = "ddd";
return myFn;
};
var f = myFunction();
f(); // "ddd"
Thanks!
This line of code will run the function myFunction and assign its return value to f.
var f = myFunction();
myFunction returns a reference to the function myFn. As a result, f is now a reference to myFn and when you attempt to call f using f() it calls myFn because that is where the reference points.
jsFiddle Demo
There is a similar approach which returns an object with functions
var init = function(){
return {
hello: function(){ console.log("hello"); },
world: function(){ console.log("world"); }
};
};
Which could then be used like this:
var f = init();
f.hello();
f.world();
In scripting languages in general and functional programming. You can use functions as you would a variable. For example: in both paradigms typically(not aware of any languages that don't) functions can be passed as parameters, etc...
Functions are objects in javascript, so they can be assigned to variables and passed around like any other value. And eventually they can be executed.
What's happening here is that myFunction returns a function, which can then of course be executed.
Let me simplify your example:
// function that returns a function.
var foo = function() {
// declare a function, but don't run it right now.
var fn = function() {
return "bar";
};
// return the function object.
return fn;
}
var someFn = foo(); // function object is returned from foo()
someFn(); // "bar" is returned
// Which means you could also do this!
// the first () executes foo, second () executes the function returned by foo()
foo()() // "bar" is returned
In this example, foo() returns a function. This function is saved to the local variable someFn and then executed.
Functions that return functions are a little tricky to wrap you head around sometimes, but it's one of the most powerful features of javascript as it allows you do some very tricky things.
This little gem is giving me a bit of a headache. Let's say I create an object that returns a function, like this:
function Bar(prop) {
this.prop = prop;
var that = this;
return function() {
this.prop = that.prop;
}
}
var bar = new Bar();
console.log(bar instanceof Bar);
Bar() returns a function, as you can see. Now, Bar() instanceof Bar returns false, which isn't what I want. How do I check to see if a new Bar() is an instance of Bar? Is this even possible?
Returning any object from a constructor will use that object instead of returning an instance automatically generated by the constructor. It's a bit abstract, so here's an example to show my point:
function Foo() {}
function Bar() {
return new Foo();
}
f = new Foo();
console.log(f instanceof Foo); //true
b = new Bar();
console.log(b instanceof Bar); //false
console.log(b instanceof Foo); //true
Everything in JavaScript is an object, including functions, so the fact that your foo.bar function returns a function means that when you call new foo.bar() you're going to receive the function returned by foo.bar instead of a new foo.bar instance.
While I'm not 100% certain of what you're trying to do exactly, you can check whether a function is being called as an object initializer or as a function simply by using instanceof on the context. This pattern is often used for forcing object initialization:
function Foo(...arguments...) {
if (!(this instanceof Foo)) {
return new Foo(...arguments...);
}
//do stuff
}
This allows Foo to be called as a function and still return a new Foo instance:
a = new Foo(); //a instanceof Foo
b = Foo(); //b instanceof Foo
Not entirely sure why you'd want to do what you are doing but I see what the issue is.
In the scope of 'test', this.bar is the function bar(prop) rather than the function returned as a result of executing this function, if that makes sense. However, new this.bar('hi') will be first executing bar('hi'), which returns an anonymous function that then acts as the constructor.
In other words, you are comparing an instance created from the anonymous function with a different function so instanceof is correctly returning false.
The following logs 'true' but may not be what you are looking for:
function foo() {
this.test = function() {
var cls = this.bar('hi');
console.log(new cls() instanceof cls);
};
this.bar = function bar(prop) {
this.prop = prop;
var that = this;
return function() {
this.prop = that.prop;
}
}
}
var test = new foo();
test.test();