For some strange reason, when calling a function that assigns this to thisObj, I get an error:
TypeError: thisObj is undefined
Here's what I've got:
function templateObject()
{
"use strict";
var thisObj = this;
function _loadBackgroundImages()
{
"use strict";
// something happens here
}
thisObj.initialise = function()
{
"use strict";
_loadBackgroundImages();
};
}
The function is then called using the instantiation like so:
var templateObj = templateObject();
templateObj.initialise();
Can't figure out why I get the error - any idea?
Use new:
var templateObj = new templateObject();
Calling function with new will pass newly created empty object as this to the function and then return it to templateObj.
When you call a function like you've done (i.e. not as a method of an object):
templateObject()
Then, if you’re in strict mode, this will be undefined inside that function.
As #mishik pointed out, it looks like you wanted templateObject to be a constructor function, and to use it as such, you need to call it with the new keyword before it:
var templateObj = new templateObject();
One style note: it's conventional in JavaScript to name functions intended to be used as constructors with an initial capital.
That might make mistakes like this marginally less likely, as it'd look odd to see a function with an initial capital called without new:
function TemplateObject() {
...
}
var templateObj = new TemplateObject();
Related
I have JavaScript Closure methods I need to convert in to TypeScript. I am not able to do that. Please help me. How to write a function inside
a function in TypeScript?
var postPonedMethod1 = function() {
var postPonedMethod2 = function() {
this.getClaimNotices();
this.gridServices.get();
//$scope.gridServicesReciepts.get();
$scope.setDataLoading(false);
};
postPonedMethod2();
}
Your problem is the use of this: postPonedMethod2 refers to this, but it isn't a function defined on a class or object. If you're using popular TypeScript options --noImplicitThis or --strict, TypeScript will complain, because it is possible that you will eventually call postPonedMethod2 in a way that does not provide the expected this instance. In fact, in JavaScript's "strict mode" ("use strict";) you might find that this is undefined where it wasn't before.
In strict mode, however, if the value of this is not set when entering an execution context, it remains as undefined, as shown in the following example:
function f2() {
'use strict'; // see strict mode
return this;
}
f2() === undefined; // true
If possible, I'd switch to defining your AngularJS component as a class, calling this.postPonedMethod1() and this.postPonedMethod2() for clarity.
In general in TypeScript, the solution is to type the "this" outside a class is to define an argument called this as your function's first parameter, which tells TypeScript what type to expect. To temporarily get through the problem, though, you can explicitly set this: any. This defeats the purpose of TypeScript here, because any provides no type checking at all, but it would allow you to solve the problem later in a different commit.
That fixes the typing, but you'll still need to ensure that the value of this is set correctly where you call postPonedMethod2. This would mean one of:
Using an arrow function () => { instead of function () { for postPonedMethod2. An arrow function explicitly does not redefine this.
Calling bind(this) where postPonedMethod2 is defined, or using call as in postPonedMethod2.call(this) where you call it.
Avoiding "use strict" with --noImplicitUseStrict, if you're otherwise trying to emit a module.
Saving the outer value of this to a place where it won't be redefined, as I show below.
var postPonedMethod1 = function() {
var postPonedMethod2 = function() {
this.getClaimNotices(); // error: 'this' implicitly has type 'any' because it does not have a type annotation.
this.gridServices.get(); // error: 'this' implicitly has type 'any' because it does not have a type annotation.
//$scope.gridServicesReciepts.get();
$scope.setDataLoading(false);
};
postPonedMethod2();
}
var fixedPostPonedMethod1 = function(this: any) { // Do better than "any" if you can.
var component = this; // Store the enclosing "this".
var postPonedMethod2 = function() {
component.getClaimNotices();
component.gridServices.get();
//$scope.gridServicesReciepts.get();
$scope.setDataLoading(false);
};
postPonedMethod2(); // You could also call "bind".
}
It works for me like below
var postPonedMethod1 = () => {
var postPonedMethod2 = () => {
this.getClaimNotices();
this.gridServices.get();
//$scope.gridServicesReciepts.get();
$scope.setDataLoading(false);
};
postPonedMethod2();
}
I've got 3 codes :
var control = new Control();
function Control() {
this.doSomethingElse = function() {...}
this.doSomething = function () {
control.doSomethingElse();
}
}
Or
var control = new Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
}
Or
var control = Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
return self;
}
Important : The function is a controller, and just declared once. Then I'm using "control" everywhere in my code...
I was wondering if the control.doSomethingElse() was slow ?
In the end, what is the right thing to do and/or the fastest code in those exemple ?
Thanks !
The first is wrong - an object should never internally use the variable name by which it is known outside. Other code could change that variable to point to something else, breaking this code.
The third is also wrong - when calling Control() without new the assignments to this.foo inside will end up getting attached to the global object (except in strict mode, where there's no implicit this on bare function calls, so the assignment to this.doSomethingElse tries to attach to undefined, causing a runtime error).
That only leaves the second as appropriate, but ultimately it's a question of correctness, not performance.
Do not define methods in constructor - that means defining them every time an instance is created. Use Control.prototype.foo = function() {} instead. Also you do not need to return this if you're using new operator - that's the whole point of new operator.
The recommended approach is this:
function MyClass(param1) {
// Here we're changing the specific instance of an object
this.property1 = param1;
}
// Prototype will be shared with all instances of the object
// any modifications to prototype WILL be shared by all instances
MyClass.prototype.printProperty1 = function() {
console.log(this.property1);
}
var instance = new MyClass("Hello world!");
instance.printProperty1(); // Prints hello world
To understand this code, you need to understand javascript's prototype-based inheritance model. When you create instance of MyClass, you get a new object that inherits any properties present in MyClass.prototype. Read more about it.
Also I wonder:
The function is a controller, and just declared once.
If you're not using this multiple times, you don't need to create something like class. You can do this instead:
var control = {doSomething:function() { ... }};
I assume you are used to Java, where everything must be a class, whether it makes sense or not. Javascript is different, you can also make single objects or functions as you need.
I'm new to JavaScript programming.I wrote an IIFE that will help me improve my understand. My intention is to define a $ function that when called will call itself as a constructor. When the code is run, it generates an error 'Too much recursion'. I don't know what the problem is.
(function() {
//check the global host object
var root = this;
var inside = "inside";
var $ = function () {
return new $(); //this line generates an error 'Too much recursion.'
}
$.check = function(obj) {
console.log(inside);
}
//add the $ to global object
root.$ = $;
}).call(this);
var ins = $();
console.log(ins);
var $ = function () {
return new $(); //this line generates an error 'Too much recursion.'
}
This function is repeatedly calling itself, which is why you see the Too much recursion. error. You aren't distinguishing between a regular function call and a new call.
My intention is to define a $ function that when called will call itself as a constructor.
The simplest way is to explicitly check this:
var $ = function $() {
if(!(this instanceof $)) return new $();
// ... from this point on, behave as if called via new
}
this line generates an error 'Too much recursion.'
Right. You have a function assigned to the $ symbol which calls the function assigned to the $ symbol. So each call (whether direct or via new) will run the code in that function, which makes another call to it, and so on until you exceed the engine's willingness to recurse. To avoid that, have $ do something else.
It's because you have created an infinite loop. By using parenthesis when returning your new var instance you are recursively calling that function with no parameters. I'm not sure what you are trying to accomplish, but you might want to have $ create a new object "{}" instead and then you can extend methods off of that reference. Look into singleton patterns, that will allow you to create a new instance of something.
*edit, and just to be clear your problem doesn't have anything to do with it being an IIFE, you would encounter this same error anywhere you tried to call a new function on itself in this manner.
I'm using the introjs library.
See the original code here.
I want to be able to write var = new IntroJs() rather than call the start() method.
How can I achieve that?
Why not simply wrap up the factory that introJs provides and call start on it in your wrapper?
You can do it externally with something like this (untested):
var introJsWrapper = function(targetElm) {
var ijs = introJs(targetElm);
ijs.start();
return ijs;
};
Or you can do that inside a fork of the introJs code by exposing it as a property of the main function, e.g.:
var introJs = function (targetElm) {
if (typeof (targetElm) === 'object') {
// ...
}
introJs.autoStart = function(targetElm) {
var ijs = introJs(targetElm);
ijs.start();
return ijs;
};
Note that in introJs, the main function is just a very thin parameter-testing/changing wrapper already around the internal constructor. Calling it indirectly invokes the constructor. So there is really no need to access this internal constructor function directly, as far as I can see.
Well, this should be it. I assume these are enclosed in a closure since the code seems to imply that there is some internal functions going on. Here's what I gathered. It's not a complete implementation since I don't know how the this when calling new IntroJS gets used in the constructor. All I know is that your prototype functions are operating on some properties.
//internal functions
function _mergeOptions(target){/*implementation*/}
function _introForElement(el){/*implementation*/}
function _goToStep(step){/*implementation*/}
function _exitIntro(target){/*implementation*/}
function _setHelperLayerPosition(nodeList){/*implementation*/}
//constructor
function IntroJs(first){
this._options = {};
this._introChangeCallback;
this._introCompleteCallback;
this._introExitCallback;
}
Just an empty constructor will suffice. As Jan said, it's pretty useless, but if you like the notation...
http://plnkr.co/edit/eFzkKJ14TeaMY44GDxR2
Ok, so basically this solved my problem:
introJs.fn = IntroJs.prototype = {
...
initialize: function() {
return this;
}
...
}
Now, calling introJs().initialize() gives me the library without calling the start() method.
How can I define a function's prototype in JavaScript? I want to do this like I would do it in C where you would do something like:
void myfunction(void);
void myfunction(void){
}
So is there any way to do this in JavaScript? I'm asking this because of the function declaration order that is required in JavaScript.
Edit:
I have an object:
function something(){
var anArrayOfSomethingObjects;
aPrivateFunction(){
// does some stuff
anArrayOfSomethingObjects[3].aPublicFunction();
}
return {
functionA: function() { },
aPublicFunction: function() { },
functionC: function() { }
}
}
privateFunction needs to access publicFunction which is declared afterwards.
How can I do this?
JavaScript is dynamic language there is no need to do that. Meaning Javascript has dynamic binding and dynamic typing, so the check will be on the run time. So no need to define forward declaration like in static languages.
Reply to edit:
Even in this case you still do not need to define forward declaration. Once object will have that method or field in run-time it will work fine. But you probably tackled to the problem of scoping in JavaScript, assuming you asking your question after something gone wrong.
you have to really understand what is a dynamic language, and why your question doesn't really make a lot of sense. your problem is not about 'definition vs. declaration' like on C, it's most about statements order.
in JavaScript (as with most dynamic languages) a function definition like this
function whatever (params) {
...
}
is in fact syntactic sugar for an assignment statement like this:
whatever = function (params) {
...
}
as you can see, whatever is in fact a variable, and it's assigned a function value. so you can't call it before assigning it.
Of course, execution order doesn't have to follow lexical order. If that's your case, you just have to make sure you assign the needed variable before using it. If it's a local variable and you want closure semantics, you can define it first and assign later, like this:
var myfunc = undefined;
function first () {
...
myfunc (...);
...
}
myfunc = function (...) {
...
}
What you are looking for is the Module pattern:
function Something()
{
var someObjects;
var pub = {};
var privateFunction = function()
{
pub.publicFunction();
}
pub.functionA = function() {};
pub.functionB = function() {};
pub.publicFunction = function() {};
return pub;
};
More info and examples: http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/