Using instance functions from constructor using WinJS - javascript

I have a function defined roughly as follows:
var myNamespace = WinJS.Namespace.define("MyNamespace", {
myClass: WinJS.Class.define(
function (myVariable) {
myFunction(myVariable);
},
{
myFunction: function FunctionMine(myVariable) {
// Do stuff
}
...
I'm using WinJS to write a windows store app, and the above format doesn't seem to work - it doesn't recognise myFunction as a function. Is it possible to reference an instance member of the class from the class constructor?

You need to use "this.myFunction".
Your function isn't in the scope to let you call it in that way.

Related

Get instance of class (this) in function inside instance object - typescript/angular

I have a separate object that manages a particular dialog box. Consider the following code. As it is very easy to imagine what the functions do, I'm however unable to access the instance of the class. I tried using the traditional that = this approach.
export class Whatever implements OnInit {
that = this;
dialog = {
data:{},
open:function() {
//way to access 'that' variable
},
close:function() {},
toggle:function() {}
}
//other declarations and functions
}
As my application is scaling, I'm having too many functions inside this service. So i'm trying to club some of these functions into objects, which will make the code much cleaner.
Also if there is any better approach to this, I'd love to know. Thanks.
Best way would be to replace the function(){} with the ES6 arrow functions, which holds your this context like so () => {}.
You can also use functions(){}.bind(this), but it's much better to just use arrow functions. Both will keep your reference to this as expected in the body of the function
You have to use arrow functions to not lose the context(this);
export class Whatever implements OnInit {
dialog = {
data:{},
open:() => {
//'this' will point to Whatever class's instance
},
close:() => {},
toggle:() => {}
}
//other declarations and functions
}
In your code, that isn't a variable, it's a property of the Whatever instance.
Your dialog is also a property of the Whatever instance. In calls to its methods, this will vary depending on how they're called.
To ensure they access the Whatever instance, you can use arrow functions and use this within the functions:
export class Whatever implements OnInit {
dialog = {
data: {},
open: () => {
// use `this` here
// use `this.dialog.data` to acccess the data above
},
close: () => {},
toggle: () => {}
};
//other declarations and functions
}
This works because class fields declared as you've declared them there are effectively initialized as though they were inside your constructor, and within the constructor, this refers to the instance. Arrow functions close over the this of the context where they're created (just like closing over an in-scope variable).

Get method's instance owner

Given a class and an instance of it
var class=function() {
this.propA=99;
this.methodA=function() {
console.log(this.propA);
};
};
var object=new Class();
I'd like to be able to perform a call to methodA where this will be the instance of it and the example (this.propA) will work. Exactly as
object.methodA.call(object);
but without having any reference to object. Like this in some pseoducode:
var methodToCall=object.methodA;
...
...
methodToCall.call(getInstanceOwnerOf(methodToCall));
The objective of this is to pass methods as callbacks to async functions and keep this as the instance when the method is called.
Some workarounds would be to pass method and object to that async function, or to store this in a local variable, but these are the things I want to avoid.
Use bind to bind to the context you want function called in. Note this returns a NEW function which is not the same as the original.
I usually create the new function and give it a different name but you can do it multiple ways.
To be more specific, you can't be sure this is the class the function is declared in, depends on how you called the function and if you are in strict mode.
an example below:
Fiddle: https://jsfiddle.net/f7af535L/
class SomeClass {
constructor(someVar) {
this.myVar = someVar;
this.publicSayVar = this.sayVar.bind(this);
}
sayVar() {
console.log(this.myVar);
}
}
var object = new SomeClass("hello");
var testcall = object.publicSayVar;
testcall();

Scope issue inside objects that are inside objects

I've come across a problem while trying to build a simple jQuery plugin, having to do with scopes I guess.
The problem in short: A class (A) creates an object (B), in which a property (C) is set to one of the class methods (D). How can I access class A's methods not contained inside the object (B) through the property ( C)?
Longer version (code below): I'm declaring an object (lets call it publicMethods) inside the plugin, comprised of a bunch of methods. These methods should be some default methods (declared inside the plugin), or user declared ones if the user has declared her own when initializing the plugin.
The idea is that when the user defines her own custom method, there should be some functions and variables accessible to her (like this.someVar) in that function.
This creates some limitations though.
I want the default methods to have access to some internal functions and variables, not contained inside the object publicMethods. But when I access these methods through the object they are inside, instead of calling them directly, I do not have access to another variables/functions not inside that object.
I'm trying to find a way to let the default methods have access to it's class siblings. I know I can do some conditional statements before calling the method (if it is user defined or not), or even declare a global variable pointing to "this", but I'd rather keep it clean.
var Plugin = function (opt) {
this.settings = $.extend({
"someVar" : "Value",
"someFunc" : null
});
this.anotherVar = "Hello World";
this.setPublic();
this.run();
}
Plugin.prototype = {
setPublic: function() {
this.publicMethods.someFunc = this.someFunc;
if ($.isFunction(this.settings.someFunc)) {
this.publicMethods.someFunc = this.settings.someFunc;
} else {
this.publicMethods.someFunc = this.someFunc;
}
},
someFunc: function(arg) {
return this.anotherVar; // returns type error the second time
},
run: function () {
this.someFunc();
this.publicMethods.someFunc();
}
}
From MDN: Function.prototype.bind():
The bind() method creates a new function that, when called, has its this keyword set to the provided value, [...].
So the following should work:
setPublic: function() {
this.publicMethods.someFunc = this.someFunc.bind(this);
if ($.isFunction(this.settings.someFunc)) {
this.publicMethods.someFunc = this.settings.someFunc.bind(this);
}
// This is redundant anyway:
/* else {
this.publicMethods.someFunc = this.someFunc.bind(this);
}*/
},

Scope private classes in a separate file

Is there a way to create a private class in a separate file without polluting the global namespace? Currently I just create a sub-namespace and put all of the private classes that other public classes need to function, but is there a way to just make a class altogether private, yet in another file?
You are probably looking for the "Module Pattern" in JavaScript. The Module Pattern name can refer to a lot of different patterns but the basic concept to to declare functions and attributes that are only available to a function which has already been called. Like this:
myModule = function () {
var me = {},
iAmPrivate = 1;
function privateFunc() {
// stuff can access iAmPrivate and iamPublic
}
me.iamPublic = 1;
me.publicFunc = function () {
// stuff can access iAmPrivate and iamPublic
};
return me;
}());
myModule.publicFunc(); // this can be called
myModule.iamPublic; // this can be accessed
myModule.iAmPrivate // xx can't do this
myModule.privateFunc() // or this
Because of how closures and scope works, Items declared local to that function call are available to all functions declared in that function call but nothing outside of the function call. The function has been called so they can never be accessed.
You can read a lot more about it here : http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html, and of course with a Google search now that you know what it is called.

Class variable in javascript class

The solution to this question suggested the use of John Resig's class implementation. This solution covers all my needs except:
How to declare a public global variable inside this class that can be accessed from outside?
I would like to establish something like the following:
var MyClass = Class.extend({
EVENT_NAME : 'event-name',
init : function() {
// ...
}
});
// Now another file can directly read this value without creating the class object
console.log( MyClass.EVENT_NAME );
The "only" way to do what you want to do is to use a function as the "class". This way you are declaring a "class" whose public "static" members can be accessed. Something like this:
function MyObject() {
// constructor stuff here
}
MyObject.EVENT_NAME = "event_name";
console.log(MyObject.EVENT_NAME); // No need to instantiate MyObject
However, seems to me like you are mixing concepts from statically typed languages with Javascript's more dynamic stuff. Why would you want to access a member of an object that has not been created?
Declare it in the window context or don't use the 'var' keyword:
window.globalVar = somevalue
globalVar = somevalue
var MyClass = Class.extend({
EVENT_NAME : 'event-name',
init : function() {
// ...
}
return {
event_name: function() { return EVENT_NAME; }
}
});
console.log( MyClass.event_name );
Actually, to be honest, I'm not sure how the above is going to work with .extend() as I've not actually used extend() before.
However, the return { name:value } technique is a pretty common way of exposing public instance methods in objects. It shouldn't take long to test it properly, sorry I didn't have a chance to do it myself.

Categories