Referencing an object's function from another function using JavaScript [duplicate] - javascript

This question already has answers here:
Accessing an object's property from an event listener call in JavaScript
(6 answers)
Closed 2 years ago.
I have the following JS object in my code:
var myLibrary = {
name: "John",
// Functions
func1: function() {
alert(this.name);
},
func2: function() {
this.func1();
},
// On DOM loaded
onDOMLoaded: function() {
this.func1();
this.func2();
}
}
document.addEventListener('DOMContentLoaded', myLibrary.onDOMLoaded);
When I reference this code using a script tag, I get the following error (in reference to the call in func2):
Uncaught TypeError: this.func1 is not a function
This is especially weird because if I call the functions from within the DOM, they work perfectly. For example:
<button onclick="myLibrary.func1()">Func 1</button>
<button onclick="myLibrary.func2()">Func 2</button>
Clicking on the buttons does exactly what I want them to. What am I doing wrong here? And how can I fix this issue? Thanks for any help!
A demo can be found here: https://jsfiddle.net/gLxvsze0/

You should read about this is JS.
When you call myLibrary.func1() the function will be called with myLibrary context. But when you call just func1 (ie func1 = myLibrary.func1; func1()) this will be called with global Window context.
To solve your problem, you can use bind method, that creates new function linked with provided context:
document.addEventListener('DOMContentLoaded', myLibrary.onDOMLoaded.bind(myLibrary));

I think the simplest solution to the context issue is...
document.addEventListener('DOMContentLoaded',() => { myLibrary.onDOMLoaded(); });

Related

How to call a class method from inside same class method? [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I've created a class and I'm trying to call a method from inside that class from another method inside that same class. I've seen online that some people say use 'this' keyword, but as you can see from the example, that doesn't work. Can someone please explain in simple terms how to call a class method from inside another method in that same class? Thanks!
class Form {
constructor() {
}
fn1 () {
console.log('fn1 calling fn2 now:')
this.fn2();
}
fn2 () {
console.log('fn1 called me')
}
}
let myForm = new Form();
myForm.fn1();
Example can be found here
The error I keep getting is this: Uncaught TypeError: this.fn2 is not a function
There's nothing wrong with the code you show embedded into your question - that should work just fine. The issue arises when you pass a method to .addEventListener() as a callback (which shows in the code you have a link to).
Change this:
document.getElementById('call-func').addEventListener('click', this.fn1);
to this:
document.getElementById('call-func').addEventListener('click', this.fn1.bind(this));
The problem is that passing this.fn1 loses the value of this so when the listener calls the callback later, the object that it belongs to is lost and then this inside of fn1() is wrong. In addition, .addEventListener() explicitly sets the this value to the DOM element that triggered the event (which is not your object).
The same thing would happen if you did this:
let f = this.fn1;
f();
Using .bind(this) rebinds the value of this when the listener calls it.
FYI, you could also do it this way with a fat-arrow function:
document.getElementById('call-func').addEventListener('click', () => this.fn1());
Or, an older way of doing it:
var self = this;
document.getElementById('call-func').addEventListener('click', function() {
self.fn1();
});
My preference is to use .bind(this).
More explanation on event listeners and this here: "This" within es6 class method
More explanation on the general concept of how this gets set when a function is called here: When you pass 'this' as an argument

Why is a javascript function unaccessible from another script file? [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 5 years ago.
I have a problem I've been searching SO for answers to, but nothing seem to do it for me. I've referenced a question that mimics my problem but the solution still don't solve my problem.
Accessing function in another .js file with $.getScript
My problem is as I've mentioned similar. I can't access a method inside a script file from another script file. These are my codes:
page.js
$(document).ready(function () {
$.getScript('script.js').done(function () {
$('#build').append(literals.test()); // $('#build') is a span tag in the HTML-file.
}).fail(function () {
console.warn('Unable to load script file.');
});
});
script.js
(function ($) {
var literals = {
test: function () {
return 'Hello world!';
}
};
})(jQuery);
This still returns the following error even though I've built it almost exactly the same way as in the answer of the referenced question.
Uncaught ReferenceError: literals is not defined at Object.<anonymous>
What am I doing wrong here?
Because when you create a closure, anything inside of it is only visible to other things in that scope.
In JS, all functions are closures.
(function(){
// this is a closure
})()
If you want to be able to get the literals functions from outside of the closure, one option is to return it from the function...
const literals = (function($){
return {
test: function () {
return 'Hello world!';
}
};
})(jQuery);
console.log(literals.test());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Keep the context of this after a click event in a function object [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
I've got an object with functions. Here's a simplified version:
var app = {
functOne: function(){
document.querySelector('button').addEventListener('click', this.functTwo);
},
functTwo: function(){
console.log('Funct Two has Run');
this.functThree();
},
functThree: function(){
console.log('Funct Three has Run');
}
};
app.functOne();
The app in functOne attaches a click handler to button (to launch functTwo). FunctTwo is supposed to execute FunctThree but the context of 'this' is no longer 'app' (it's now the button). How do I get 'app' again from inside (or passed to) functTwo (assuming app isn't just attached to window like in the above example).
This is achieved by using Function.prototype.bind():
functOne: function(){
document.querySelector('button').addEventListener('click', this.functTwo.bind(this));
},

What's the difference between $scope.myScope = function () and function () in AngularJS [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 7 years ago.
I've recently gone into developing with AngularJS. It's confusing to me the different between these two:
$scope.myScope = function () {
var x = 'do something with variable here';
$scope.anotherScope = x;
};
and
function myFunction () {
var x = 'do something with variable here';
$scope.anotherScope = x;
}
They both seem to be able to do the same thing (I use them a lot inside controllers). Is there a best practice for when and where to use these two?
$scope.myScope = function () {};
This means your function is a property of the scope object. So you can use it in your controller , html page even in your app. it can be referenced in different modules in the same app. so you just call it in your html page using the function name directly either onclick or onchange , anyhow depending on your need.
the other definition can only be used in your controller and is not the scope of your app. however if you define your function using "this.myScope = function(){};" then you can call the function in your html by using your controller. like ng-click = "controllerName.myScope();"
the main difference is i nwhich scope the function belongs to and where all you can reference the function.
hope it helps !!!!
As mourycy already mentioned, you should use the form
$scope.myScopeFunction = function () {
...
};
only for functions which you want to call via the scope object. This is needed for function calls within your views.
For example:
<button ng-click="myScopeFunction()" />
which calls the function myScopeFunction of the current $scope object.
If you don't need to be able to call a controller method from "outside" you should use the following form:
function myFunction() {
...
};
$scope.myScop = function(){
...
};
is a function you can execute from the HTML controller.
function foo(){
...
}
is a function you can only execute on the controller's JS file.

javascript scope in requestAnimationFrame [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
I want to make a select option for animations, so whatever type is selected, it's shown on the canvas.
So i make each animation as a "class" :
(function (exports) {
function animationA() {}
animationA.prototype.init = function(){}
animationA.prototype.draw = function(){}
exports.animationA = animationA;
})(this);
Then in the main js:
var a = new animationA();
function setup() {
a.init();
}
function update(callback) {
requestAnimationFrame(function () {
update(callback);
});
console.log(this);
callback();
}
setup();
update(a.draw);
I found error occurs in the update(a.draw). It cannot access the properties of a in this line of code.
I wonder if this is a javascript scope problem?
Thanks.
You need to create a reference to the context you want to refer to inside the callback before you call requestAnimationFrame, just like you would with a normal event callback.
Var that = this;
requestAnimationFrame(function(){
that.doSimething();
});

Categories

Resources