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();
}
Related
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 am new to Javascript and am still getting my head round the various ways of creating objects i.e constructor+new, prototypal, functional & parts.
I have created what I think is an object factory using the module pattern and want to know what the correct method of calling an internal method would be. Is it via this or function name.
Here is my module:
function chart() {
function my() {
// generate chart here, using `width` and `height`
}
my.sayHi = function(){
console.log('hi');
my.sayBye();
};
my.sayBye = function(){
console.log('Bye');
};
return my;
}
var test = chart();
test.sayHi();
You can see that the first function calls the second using my.sayBye() or is it better to use this.sayBye(). Both produce the same result and run without error.
The module pattern allows you to dispense with the 'this' variable if you want to. I would probably rewrite the above code to look like this and then the question becomes moot.
function chart() {
var hiCount = 0;
function sayHi(){
console.log('hi');
hiCount++;
sayBye();
};
function sayBye(){
console.log('Bye');
};
return {
sayHi : sayHi,
sayBye: sayBye
};
}
var test = chart();
test.sayHi();
In the above code all is defined within the function chart. As JavaScript's scope is at the function level every time the chart function is called a new set of functions will be defined. And a new set of variables can also be defined that are private to the function as they are defined in the function and are not accessible from outside. I added hiCount as an example of how you could do this. The Module pattern allows privacy in JavaScript. It eats more memory than the prototype pattern though as each time a function is declared it is not shared between other instances of the same class. That is the price you have to pay in Javascript to have class variables that are private. I willingly pay it. Removing 'this' from my code makes it easier to understand and less likely that I will fall into problems of misplaced scope.
Using "this" is better approach because you would be able to bind the function directly to the parent function object.And you dont need to return anything from the function.
where as in your case you are explicitly returning another function
Here is the use of "this" approach
function chart() {
this.sayHi = function(){
console.log('hi');
}
}
var test = new chart();
test.sayHi();
Using this approach you would be able to call anything in the prototype of function "chart"
Eg
chart.prototype.hello = function(){
console.log('hello')
}
So you would be able to call the hello function from the same object(test)
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();
I have a difficulty in understanding, how my current JavaScript code works. I've managed to solve a problem in accessing private object method from event handler closure, but I'd like to know why does it work so.
The code utilizes the well-known module/plugin metaphor:
(function(module, $, undefined)
{
function myPrivateCode(e){ /*...*/ }
module.myPublicCode = function(e) { /*...*/ }
module.init = function()
{
var that = this;
$('.clickable').click(function(e)
{
if($(e.target).hasClass('classX'))
{
that.myPublicCode(e.target); // requires 'that' to work
}
else
{
// that.
myPrivateCode(e.target); // will fail if 'that' uncommented
}
});
}
}(window.module = window.module || {}, jQuery ));
In the code I set a click handler which invokes either public or private method. It's perfectly conceivable that we need to pass an object reference into the event handler closure, which is done by that local variable. What is strange to me is that myPrivateCode does neither require that as a refernce, nor fails due to its "privacy". This makes me think that myPrivateCode accesses not the appropriate object, and works somehow differently to expected way. Could someone explain what happens? Certainly I'm missing something.
Both that and myPrivateCode are available to your event handler through a closure. In short, what's going on is that every variable and function you declare inside of another function has access to the outer scope.
myPublicCode, on the other hand, is not available through closures, because it's being assigned to your module object specifically. So the only way to call it is by using module.myPublicCode() (or that.myPublicCode() as you did – but you don't actually need that there, since module is also available).
Your call to myPrivateCode(e.target); is running in the context of the anonymous function that you pass as a handler to the click function.
For more information, read up on closures.
For a simpler example, try out this code:
var foo = function () {
var a = 1;
return function (b) {
return a+b;
}
};
var bar = foo();
bar(1); // 2
bar(1) will always always gives 2, because a = 1 was in scope when the function was created. In your case, a is your that and your handler is the closed function.
http://jsfiddle.net/Fh8d3/
I'm developing a javascript application that consists of many objects and functions (object methods). I want to be able to log many events in the life cycle of the application. My problem is that inside the logger I want to know which function invoked the log entry, so I can save that data along with the log message. This means that every function needs to somehow be able to reference itself, so I can pass that reference to the logger.
I'm using javascript strict mode, so using arguments.callee inside the function is not allowed.
Here's a very simplified code sample you can run. I'm just using here alert instead of my logger for simplicity.
(function(){
"use strict";
window.myObject = {
id : 'myObject',
myFunc : function(){
alert(this.id); // myObject
alert(this.myFunc.id); // myFunc - I don't want to do this. I want something generic for all functions under any object
alert('???') // myFunc
alert(arguments.callee.id); // Will throw an error because arguments.callee in not allowed in strict mode
}
}
myObject.myFunc.id = 'myFunc';
myObject.myFunc();
})();
In the first alert - this related to myObject and not to myFunc
In the second I alert - I referenced the function by its name, which I don't want to do, as I'm looking for a generic way to reference a function from within its own implementation.
The third alert - open for your ideas.
The fourth alert - would have worked if I didn't "use stict";. I want to keep strict mode since it provides better performance, and constitutes good coding practice.
Any input will be appreciated.
If you're not familiar with "strict mode", this is a good place read about it:
JavaScript Strict Mode
Here's a very hacky way of doing it:
(function(){
"use strict";
window.myObject = {
id: 'myObject',
myFunc: function () {
// need this if to circumvent 'use strict' since funcId doesn't exist yet
if (typeof funcId != 'undefined')
alert(funcId);
},
myFunc2: function () {
// need this if to circumvent 'use strict' since funcId doesn't exist yet
if (typeof funcId != 'undefined')
alert(funcId);
}
}
// We're going to programatically find the name of each function and 'inject' that name
// as the variable 'funcId' into each function by re-writing that function in a wrapper
for (var i in window.myObject) {
var func = window.myObject[i];
if (typeof func === 'function') {
window.myObject[i] = Function('var funcId = "' + i + '"; return (' + window.myObject[i] + ')()');
}
}
window.myObject.myFunc();
window.myObject.myFunc2();
})();
Essentially, we are circumventing the 'use strict' declaration by recompiling each function from a string after we've found out that function's name. To do this, we create a wrapper around each function that declares a string variable 'funcId' equal to our target function's name, so that the variable is now exposed to the function within through closure.
Eh, not the best way to do things, but it works.
Alternatively, you can simply call a non-strict function from within:
(function(){
"use strict";
window.myObject = {
id: 'myObject',
myFunc: function () {
alert(getFuncName())
},
myFunc2: function () {
alert(getFuncName());
}
}
})();
// non-strict function here
function getFuncName(){
return arguments.callee.caller.id; // Just fyi, IE doesn't have id var I think...so you gotta parse toString or something
}
Hope that helps.
I don't think what you want to do (finding the name of the current function) is very easy to do. You might want to look into adding a preprocessing step (like is done for things like __line__ in C) but perhaps just a little OO/currying magic does the trick:
function logger(id){ return function(msg){
return console.log(id, msg);
};}
window.myObject = {
id : 'myObject',
myFunc : function(){
var log = logger('myFunc');
log(1); //prints "Myfunc, 1"
log(2); //prints "Myfunc, 2"
}
};
This is kind of a cop out but is very simple and can be reasonably mantainable if you just remember to keep the ids and function names in track.
myFunc : function _myFunc(){
alert(_myFunc); // function
}
Name your functions and reference them directly
To solve your logging purpose, use real sensible unique logging messages. If you want line information then throw an exception.