Function declaration inside function which is inside object - javascript

It is interesting, just theoretically, not in real world.
1 - How can I call inside() function from outside?
2 - Is it common practice to create such a structure?
3 - What will be the value of this in inside() function (if it is possible to call from outside)?
var obj = {
method: function(){
console.log('method function called!');
function inside(){
console.log('inside function called!')
}
}
}

How can I call inside() function from outside? -> No, JavaScript has
block level scope, hence anything defined inside function will not
be accessible outside function. It could be called a private
function.
Is it common practice to create such a structure? -> It is. If you
want your function to be hidden from other part of your execution
cycle.
What will be the the value of this in inside() function (if it is
possible to call from outside)? -> Value of this depends on how
the function is invoked. In your case, this will be window if
function is called without any context hence global(window)
context
var obj = {
method: function() {
console.log('method function called!');
function inside() {
console.log(this);
console.log('inside function called!');
}
inside();
}
}
obj.method();

Related

"this" returning undefined, after function call

When I call one function, "this" contains all the the "stuff", but when I call a function that calls another functions, "this" returns undefined inside the second function.
Code:
class test {
test() {
console.log(this) // => returns class functions ect..
this.run(this.test2);
}
run(func){
func()
}
test2() {
console.log(this) // => returns undefined
this.function3(); // => ERROR
}
function3() {
console.log("hey")
}
}
var t = new test();
t.test();
Why does the code behave this way? and how do I resolve this issue
Ah, those are colled closures. The context (this) will be different, depending on from wich context the function will be called. For javascript a function is an object and it's binding to a class object is week. It can be detached from the class and used separately with on problem. That's why when you call this.someFunc() it gives you only a function, but not the function of this actual instance.
The most common way to bypass it is to save an object context to a separate variable and use in istead of this. Something like that:
class test {
var self = this;
test() {
console.log(self)
this.run(self.test2);
}
run(func){
func();
}
test2() {
console.log(self);
self.function3();
}
function3() {
console.log("hey");
}
}
When the function passed into run is executed, it's this is pointing to a new execution context, not the instance of the class that you are expecting.
This can be 'solved' by binding its execution context to the instance of the class, either when passed to run, e.g.
this.run(this.test2.bind(this))
Or I'm the constructor, e.g.
constructor () {
this.test2 = this.test2.bind(this)
}

How do you access an nested inner function from another outer function in JavaScript?

Please have a look at the following JavaScript snippet of code. This has to do with function scoping and hoisting in javascript. I can't call window.innermost() as it is undefined as it's not in scope.
Anyone know another way besides attaching it to the windows object. Windows Object still doesn't work in this case.
function outer(){
function callback() {
window.innermost = function() {
alert("hello from inner most")
}
}
}
(function caller() {
window.innermost(); // this is undefined
}());
You would have to call both the outer and the callback:
function outer(){
var callback = function() {
window.innermost = function() {
alert("hello from inner most")
}
}
callback(); // Call Callback
}
outer(); // Call outer
(function caller() {
window.innermost(); // should work
}());
If both of these functions are not called before you run the anonymous function, then the window.innermost won't be defined (or undefined if you will).
Also, notice that I set callback as a variable, which is an alternative way of defining a function within a function.

Scope clarification in javascript [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Explanation asked about the value of 'this' in Javascript [duplicate]
(2 answers)
Closed 8 years ago.
Simple question. Why do we have set that = this? If we dont, we are in the global scope...but why?
var myObj = {
specialFunction: function () {
},
anotherSpecialFunction: function () {
},
getAsyncData: function (cb) {
cb();
},
render: function () {
var that = this;
this.getAsyncData(function () {
// this now refers to global scope....why?
that.specialFunction();
that.anotherSpecialFunction();
});
}
};
myObj.render();
Writing that = this doesn't change the scope. The way the anonymous function is called will always end up with this being global object,* because that's exactly what the spec says should happen. Using that = this is just a workaround.
You could make this always point to myObj by using Function.call:
var myObj = {
specialFunction: function () {
},
getAsyncData: function (cb) {
cb.apply(this);
},
render: function () {
this.getAsyncData(function () {
this.specialFunction();
});
}
};
and/or using Function.bind:
var myObj = {
specialFunction: function () {
},
getAsyncData: function (cb) {
cb();
},
render: function () {
function callback() {
this.specialFunction();
}
this.getAsyncData(callback.bind(this));
}
};
* Unless you're in strict mode, in which case this is undefined.
take a look at the this keyword in JavaScript and how it works. I’m sure we’ve all come across this issue:
$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
}
});
});
this is a variable that is automatically set for you when a function is invoked. The value it’s given depends on how a function is invoked. In JavaScript we have a few main ways of invoking functions. I wont talk about them all today, but just the three ways most people use them; either when a function is called as a method, or on it’s own, or as an event handler. Depending on how a function is invoked, this is set differently:
function foo() {
console.log(this); //global object
};
myapp = {};
myapp.foo = function() {
console.log(this); //points to myapp object
}
var link = document.getElementById("myId");
link.addEventListener("click", function() {
console.log(this); //points to link
}, false);
Doing $("myLink").on("click", function() {}) means that when the element is clicked, the function is fired. But this function is bound as an event handler, so this is set to the reference to the DOM element myLink. The success method you define within the Ajax request is just a regular function, and as such when it’s invoked, this is set to the global object, as it is when any function that’s not an event handler or an object method is.
$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
var _this = this; //store reference
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
console.log(_this); //better!
}
});
});
Source: http://tinyurl.com/melbl92
EDIT: in JavaScript the "this" context depends on how your function is called, example:
function helloWorld()
{
console.log(this);
}
And here two ways to call this function:
new helloWorld(); note that if you call your function in this
way, the context of this will be the context of the function +
prototype, so your console will show this: helloWorld {}
helloWorld(); if you call your function without of the "new",
the context of "this" will be global(Window), so your console will show
this: Window about:home
Ok, with this little explanation i will try to explain now why you
have sometimes to use self/that...
Imagine that you want to use this.name inside this.hello function. Like I said before, the context of "this" depends on how your function is called, so if you want to ensure that this.name inside of this.hello function refer to this.name outside is recommended that you use self/that to avoid what happens bellow
function helloWorld(){
var self = this;//or that = this
this.name = "YourName"
this.hello = function(){
console.log(this); //the context of "this" here will be: "hello {}"
return this.name; //undefined, because you don't have name attribute inside hello function
}
new this.hello(); //note how hello is called here...
}
var test = new helloWorld();
And here a good explanation about context x scope:
http://ryanmorr.com/understanding-scope-and-context-in-javascript/

Calling function of $.fn.function

The problem is the following.
Theres is a function custom jquery function with another function inside, f.e.:
$.fn.slides = function(args){
function foo(args){
}
}
My question is now: How can I call the method foo.
foo is not a method. It is a local function. There is no way to access it from outside the function in which it is defined unless you modify that function to expose it.
For example (and I do not recommend creating globals, you should probably attach the function to some other object):
$.fn.slides = function(args){
function foo(args){ }
window.foo = foo;
}
You can't call it from outside the function, unless you return an object which has foo attached to it, something like this:
$.fn.slides = function(args){
this.foo = function (args){
}
return this;
}
$('blah').slides(args).foo(args);
Inside the function you can use it as a regular function:
$.fn.slides = function(args) {
function foo(args) {
}
foo(args);
}

How do I call this function from within JQuery?

I want to use JQuery in a Javascript program I'm working on but I ran into some issues with scope. How do I call myfunction2 from myfunction1 in this psuedo-code? (assume that a new MyConstructor object has been created somewhere and that myfunction1() has been called)
function MyConstructor(){...}
MyConstructor.prototype.myfunction1 = function(param) {
$('#some_element').click(function(){
this.myfunction2('clicked!'); //this doesn't work
});
}
MyConstructor.prototype.myfunction2 = function(param) {
}
myfunction2 can be called with this.myfunction2() when in any function of MyConstructor.
In your case you are trying to call myfunction2 inside another function that has a different meaning for this. To access myfunction2 you can create a variable for either this or this.myfunction2 that is in closure scope that extends to the function parameter of click
var self = this;
$('#some_element').click(function(){
self.myfunction2('clicked!');
});
or
var myfunction2 = this.myfunction2;
$('#some_element').click(function(){
myfunction2('clicked!');
});

Categories

Resources