I'm start working with existing rails application, and I found something i don't understand. Every js function (write as coffe) was declared in followed style.
this.functionA = function(){}
and then invoke like:
functionA()
There wasn't any namespace, so all of functions was assigned to window object.
I removed this because i thought that it is not necessary, but I get error that functionA() does not exist. Why I get this error? And is it a reason to declare function in above style?
Related
This is my test function:
var testFolderId = 'di98kjsdf9...';
function testGetFolder(testFolderId){
folder = DriveApp.getFolderById(testFolderId);
Logger.log("folders: " + folder);
}
It fails when I do this. The error says: INVALID ARGUMENT
However, if I hardcode the id into the 'DriveApp.getFolderById' function, it works.
Any explanation? This makes no sense to me.
When a function is called directly from the script editor/menu/button click/triggers, the following sequence of actions happens:
First, Entire script is loaded and All global statements are executed. This is equivalent to loading a web page with all your script in script tags: <script>...code.gs..</script>
The function you called is called. This is like adding callMyFunction() at the bottom of the already loaded script.
Except in case of triggers, The function you called is run without passing any arguments. Thus all arguments are undefined
Caution ⚠️: If the function is called by a trigger, the first parameter passed is usually the event object, while the rest of the parameters are undefined.
var testFolderId="1dhhddci6";
//When this function is called by IDE, it called without passing any arguments
function testGetFolder(testFolderId){//<=same as calling `testGetFolder()` or `testGetFolder(null)`
//testFolderId is declared in local scope , but is undefined
folder = DriveApp.getFolderById(testFolderId);//<= testFolderId is undefined
Workarounds:
Use default parameters:
//When this function is called by IDE, it called without passing any arguments
function testGetFolder(testFolderId="dhhddci6"){//<=same as calling `testGetFolder()`, but `testFolderId` is passed a value. Also same as calling `testGetFolder("dhhddci6")`
//testFolderId is declared in local scope and is defined(declared and intialized with a value)
folder = DriveApp.getFolderById(testFolderId);//<= testFolderId is "dhhddci6"
If global variables are used, Then the arguments should not be declared.
var testFolderId="1dhhddci6";
//When this function is called by IDE, it called without passing any arguments
function testGetFolder(){//<=same as calling `testGetFolder()`
//testFolderId is NOT declared in local scope, so variable is looked up in global scope(where it is defined)
folder = DriveApp.getFolderById(testFolderId);//<= testFolderId is "dhhddci6"
Further reading:
Scope
Closures
Default parameters
Hoisting
Event objects
I have a function in a component that calls another function and both have the same name.
It works, both of the functions run
I would like to know why does it work (see my assumption below)?
A followup question, what if i want to call the external function recursively should i use this.myMethod()?
Is this pattern safe to use?
Example:
myMethod(){
const {myMethod} = this.props;
if(typeof myMethod == 'function'){ // i was sure this will check the external myMethod func
myMethod(); // i was sure it will call the external myMethod func.
}
// what if i want to call to the external "myMethod" func (recursively)?
}
I assume that the engine is searching for a function named myMethod inside the body of external myMethod (lexical scope?) and it finds it.
can anyone confirm this assumption?
EDIT
Just to make my question more clear about how common and safe this pattern is.
Let's say i have a component of Item and it has an onTouch prop of PropTypes.func, i would like to run some internal logic inside my own function and then run the function that received via the props as a callback or something similar.
Should i bother finding a new name to my internal function like onInternalTouch or is it safe to stick with the same name onTouch?
onTouch(){ // is this common practice?
const {onTouch} = this.props;
// ... internal component logic
onTouch();
}
onInternalTouch(){ // or should i bother finding a new name?
const {onTouch} = this.props;
// ... internal component logic
onTouch();
}
Please note that component myMethod method is defined as object (class) method so to call it from any component method you have to use this.myMethod(). There's no possibility that calling myMethod() (without this.) inside any component method will call component method with the same name. If you didn't define myMethod variable inside the method and tried to call it you'd get an error telling that myMethod is not defined. So such code will give you mentioned error:
myMethod(){
myMethod();
}
When you call a function JS firstly try to find such function defined in closest scope (in your case inside component myMehod method body), if there's no such function JS moves to next (parent) scope (in your case it'd be the same scope in which react component is defined) and tries to find it again and so on.. But it's imporant that component methods are not defined in any of those scopes but are defined as class methods so you have to use this.myMethod to tell JS that you mean method defined on 'this' object. Generally to call any object method you have to use method name associated with an object.
Situation would be different if it wasn't component methods but normal functions. Consider such code:
//here is outer scope
function myMethod() {
//here is inner scope
myMethod(); // this will call function defined in outer scope
}
myMethod();
it would give you 'too much recursion' error - there is no myMethod function defined in inner scope so JS uses function defined in outer scope.
If you now override outer function with inner variable with the same name there would be no errors:
//here is outer scope
function myMethod() {
//here is inner scope
var myMethod = function() {
console.log(12);
}
myMethod();
}
myMethod();
In above code variable defined in inner scope overrides function defined in outer scope so JS finds myMethod in inner scope and even doesn't try to search for myMethod in outer scope.
Back to you question - yes, if you want to call the external function recursively you have to use this.myMethod().
Question edit update:
As for your question regarding naming practice both options will work. It's just a matter of code readability and good practices. I'd personally use different meaningful names. In your example I'd use e.g. handleTouch for method name and touchCallback for prop name. Generally it's more difficult to understand code using the same names for different functions - you have to pay more attention to grasp what function does and where it comes from (is it component method or function passed as prop?).
Generally it's easy to get confused if you use the same names especially if someone else reads your code. Of course it's totally ok if two or more components have method with the same name if they do similar job but if one function calls another function IMO they should have different names because they have different purpose which should be reflected in their names.
I have a class that I use to load external resources via an XMLHttpRequest (this is for WebGL) so I'm loading models, shaders etc. My plan was to put a loading display up whilst it did all these requests and then when it's finally complete I want it to run a callback function from the original function that created it. However, I'm getting strange results when I try to run that call back (such as it has no access of any of the objects within the class that did the loading).
I can get around this problem by passing "this" into the loading class and then doing
self = this;
promise(self.callback());
but I'd much rather specify the function that I want it to callback to after its done the loading. Does anyone know if this can be done? My code looks like this:
Main Class
this.loadingClass = new LoadingClass(this.LoadingComplete, resources);
Main.prototype.LoadingComplete = function()
{
// Returns undefined if i specify the callback function instead of just "this"
console.log(this.loadingClass.anyOfTheMembersOfThisClass);
}
Loading Class
LoadingClass = function(callback, resources) {
..
Promise.all(resources).then(function(loadedResources)
{
..
callback();
});
}
When you pass the function object as
(this.LoadingComplete, resources)
the object to which it was bound, will not be passed. So, only the function object LoadingComplete is passed to LoadingClass and when it is invoked as
callback()
the this value will be undefined (in strict mode).
To fix this,
you need to bind the this object, like this
new LoadingClass(this.LoadingComplete.bind(this), resources)
if your environment supports ES2015's Arrow functions
new LoadingClass(() => this.LoadingComplete(), resources);
In both these cases, when the LoadingComplete is invoked from LoadingClass, the this will be retained.
You are detouching callback (read about "this") function from the root object, so of course it loses context. Specify bindingContext explicitly with Function.prototype.bind method:
this.loadingClass = new LoadingClass(this.LoadingComplete.bind(this), resources);
I have a clarification in using IIFs in javascript .
I have downloaded a javascript file called called test.js as follows and I have got following questions after googling IIFs:
define(function () {
(function (window) {
this.test = function() {};
Test.prototype.function1 = function(){
//Do something
},
function Delete(){
//Code to Delete
}
window.Delete = Delete;
})(window);
});
I do have the following questions:
Is the line,
this.test = function() {}; a constructor?
If so can I have 2 constructors in a single file like for example:
this.test = function() {};
this.test2 = function() {};
And also, why would I need a constructor when I know that this is an automatically invoked file where everything gets executed initially itself.
Is this a private function?
Test.prototype.function1 = function(){
//Do something
},
Does this not get automatically? Should I need to create an object of the test and then invoke it?
Is this a public function?
function Delete(){
//Code to Delete
}
window.Delete = Delete;
The last line of the above says that . If it is so then whats the difference between first and second function?
What is keyword window here?
It's worth noting that this code will fail with an error, as Test is undefined, and you can't set the prototype property on undefined.
In JavaScript, any function can be a constructor. It's up to how you use it. You can add functions and properties to the .prototype property of any function, and any objects created from it using new will get them from the prototype chain. In your case, this.test = function(){} doesn't look like a prototype.
There's no such things a "public" or "private" functions in JavaScript, there's only what's exposed via return out of the function (or in your case, by using the global window object, which is considered bad practice) If the Test function is exposed somewhere, then Test.prototype.function1 is also exposed. All prototype methods are "public".
Yes, sort of. Like I said, "public" or "private" isn't a thing in JavaScript. You created a function and placed it on the window object, which is global. Essentially, you've made the function global.
window is the global browser object. Although when used like this (function(window) { ... })(window), the first window is the name of the parameter, (and any instances of window inside the function reference to that parameter, and the second one (passed to the function call), is the global window object.
Further reading:
The Revealing Module Pattern
I read some JS module design patterns recently. I came across this small code snippet as below.
(function(window) {
var Module = {
data: "I'm happy now!"
};
window.Module = Module;
})(window);
Still not quite understand this code well, my questions are:
How to use/call this module outside this particluar JS file? Need I
assign a variable to this module? e.g. var module1 = (...)(...);
Could anyone explain what the window parameter here stands for?
Is it a good practice to have two/three such kind of modules in the
same file?
The main reason to create an anonymous function in this case is to prevent global object pollution. It's not really a module pattern.
The problem arise when you declare a variable. Without the function scope, the variable will be added to the global object (window). If you were to declare the variables within a function. It would add the variable to the function scope without polluting the global object window.
What happen is that a javascript file could add a variable named foo and on a different file use that variable named foo too. Unless you really want to have a variable shared by two javascript files, it would probably create conflicts and bug that are difficult to fix.
For example: a.js
var foo = "one"
b.js
var foo = "two"
c.js
alert(foo)
In this case, the alert box might show either "one" or "two", depending of the order in the javascript files are included.
But having this a.js:
(function () {
var foo = "one"
})()
b.js
(function () {
var foo = "two"
})()
c.js
(function () {
alert(foo)
})()
This would create an error as you cannot alert a non declared variable.
One way to detect undefined variables, is to make sure to execute the javascript code in strict mode.
To do that, add the string "use strict" at the top of the file or function.
function () {
"use strict"
...
}
Undeclared variable will raise errors and it should be possible to fix the code that way.
Also, if you forget to declare a variable with the var keyword, it might end up adding the variable to the global scope even if the code is scoped into a function. The only way to prevent global scope pollution is to run the code in strict mode.
In the code snippet that you provided, the module with name Module is explicitly added to the window object. You can access the window object from any place in javascript unless the window name is ghosted by an other variable.
Now, back to the modules. If you want to define modules, it can be done in many ways. As an exemple, you could create an object on the window object called modules. In this object, you'll insert your modules.
module.js
window.modules = {}
foo.js
(function (window) {
var module = {}
...
window.modules.foo = module
})(window)
This variant isn't super good as you have to manually add the module to the modules object. You have to manually modify the window object, and that can be subject to errors.
modules.js
window.modules = {}
function define(name, constructor) {
var module = {exports: {}}
constructor(module)
window.modules[name] = module.exports
}
function require(name) {
return window.modules[name]
}
foo.js
define("foo", function (module) {
module.exports.one = function () {
return 1
}
module.exports.plus = function (a, b) {
return a + b
}
})
bar.js
define("bar", function (module) {
module.exports = function () {
var foo = require("foo")
return foo.plus(foo.one(), foo.one())
}
})
This is a module definition that looks a bit like module defined with http://requirejs.org/. It is quite basic as it doesn't take into account module dependencies so if bar is loaded and used before foo. Then the require method won't be able to return the module.
Also, if you want to store modules without having them visible into the global scope, you can only define the require and define method on the window object and hide modules into an anonymous scope like this:
(function (window) {
var modules = {}
function define(name, constructor) {
var module = {exports: {}}
constructor(module)
modules[name] = module.exports
}
function require(name) {
return modules[name]
}
window.define = define
window.require = require
})(window)
This way, define and require are the only function that can give you access to modules. Other modules won't be able to modify other modules without requiring them first. This can be useful when using third parties script that could conflict with your module system.
In fact this is not a module, but a Self-Invoking Ananymous function or an Immediate function which gets an object in parameter and assign a Module property to it:
The page window is a parameter passed to this function.
So an object named Module containing a data property is assigned to window.
JavaScript Self-Invoking Functions:
A self-invoking expression is invoked (started) automatically, without being called.
Function expressions will execute automatically if the expression is
followed by ().
You cannot self-invoke a function declaration.
You have to add parentheses around the function to indicate that it is
a function expression
So As you can see Immediate Functions can't be called as its name states it will be immediately executed and by its self, no other function or scope can execute it.
For better reference take a look at :
Javascript Self Invoking Functions.
Self-Invoking Functions section in JavaScript Function Definitions.
And concerning your last question about its benefits and good practices as shown on the given Article reference:
Where to use self-executing functions?
One obvious situation is when you want to auto-run a function like I
showed in above example but that is trivial. If you are in a situation
where you want to run a piece of code repeatedly like updating
something in the database based on user interaction or fetching
records from database every 10 seconds or you want to load new stories
via ajax similar to how facebook does on its homepage or some other
similar situation, one would normally go for setInterval function
something like this:
setInterval(doStuff, 10000);
Above, doStuff function will get called every 10 seconds. That is the
normal approach most developers seem to go with. However, there is a
huge problem with that.
The setInterval will call doStuff function exactly at specified time of 10 seconds again and again irrespective
of whether doStuff function actually finished doing what it is
supposed to do. That is bad and will certainly get you into unexpected
results.
That is one example of where setInterval is "bad" and should be
avoided.
This is exactly where self-executing functions come in handy. We can
do the same task with the help of self-executing function along with
setTimeout like this:
function foo(){
// your other code here
setTimeout(foo, 10000);
}();
This code will also repeat itself again and again with one difference.
setTimeout will never get triggered unless doStuff is finished. A much
better approach than using setInterval in this situation.
Calling it from another file:
And if this function is on another file it will be called automatically if this file is included.
Why do we use Self-Invoking Functions in JavaScript?
And if you ask yourself why do we use these functions, self-invoked function are used to manage Variable Scope.
Take a look at the answer here for further information.