I think this has been addressed somewhere, at some point, just for the life of me I can't remember so here's my question:
I'm doing some javascript work that will be loaded into an existing application. This application has crap loads of functions available and hardly any of it is known to me except some that I want to actually use. So lets say that I know for a fact that window.srslyUsefulFunction will be available to me and I don't care much for porting this in to a typescript definition.
So the question is how do I use window.srslyUsefulFunction in my own typescript file without creating a definition for it?
Example:
class MyClass {
public MyMethod (id : string) : void {
// do something
var result = window.srslyUsefulFunction(id);
// do something (with the result)
}
}
You can add the function to the Window interface and then use it in your TypeScript program:
interface Window {
srslyUsefulFunction(id: number): void;
}
class MyClass {
doSomething() {
window.srslyUsefulFunction(1);
}
}
I have simple workaround.
In index.html
function playIntro() {
intro = new lib.intro();
onlinePlayer.contentContainer.addChild(intro);
stage.update();
}
in my Main.ts I call it like that:
private onClick(event): void {
if (window.hasOwnProperty('playIntro')) {
window['playIntro'].call();
}
}
So... if you want to call "blind" js function from global scope, just use window["foo"].call();
Check if the function exists. If it doesn't, declare it:
if(!window.hasOwnProperty('srslyUsefulFunction')
|| typeof window['srslyUsefulFunction'] !== "function"){
window['srslyUsefulFunction'] = function(){
console.log("You're only running a dummy implementation of srslyUsefulFunction here!");
};
}
Related
I'm trying to write debugging tools and I would like to be able to get the class name of the caller. Basically, caller ID.
So if I have a method like so, I want to get the class name:
public function myExternalToTheClassFunction():void {
var objectFunction:String = argument.caller; // is functionInsideOfMyClass
var objectFunctionClass:Object = argument.caller.this;
trace(object); // [Class MyClass]
}
public class MyClass {
public function functionInsideOfMyClass {
myExternalToTheClassFunction();
}
}
Is there anything like this in JavaScript or ActionScript3? FYI AS3 is based on and in most cases interchangeable with JS.
For debugging purposes you can create an error then inspect the stack trace:
var e:Error = new Error();
trace(e.getStackTrace());
Gives you:
Error
at com.xyz::OrderEntry/retrieveData()[/src/com/xyz/OrderEntry.as:995]
at com.xyz::OrderEntry/init()[/src/com/xyz/OrderEntry.as:200]
at com.xyz::OrderEntry()[/src/com/xyz/OrderEntry.as:148]
You can parse out the "caller" method from there.
Note that in some non-debug cases getStackTrace() may return null.
Taken from the documentation:
Unlike previous versions of ActionScript, ActionScript 3.0 has no
arguments.caller property. To get a reference to the function that
called the current function, you must pass a reference to that
function as an argument. An example of this technique can be found in
the example for arguments.callee.
ActionScript 3.0 includes a new ...(rest) keyword that is recommended
instead of the arguments class.
Try to pass the Class name as argument:
Class Code:
package{
import flash.utils.getQualifiedClassName;
public class MyClass {
public function functionInsideOfMyClass {
myExternalToTheClassFunction( getQualifiedClassName(this) );
}
}
}
External Code:
public function myExternalToTheClassFunction(classname:String):void {
trace(classname); // MyClass
}
I've just started with TypeScript and I'm trying to understand why the following inline object definition isn't considered valid. I have a collection of objects - their type is irrelevant (to me), but they implement the interface so that when I iterate through them I know that the interface methods will be present in each object in the collection.
I came across a "compiler" error when I tried to create an object with private information required to implement the required method:
interface Doable {
do();
}
function doThatThing (doableThing: Doable) {
doableThing.do();
}
doThatThing({
private message: 'ahoy-hoy!', // compiler error here
do: () => {
alert(this.message);
}
});
The compiler error message is "Argument of type '{ message: string, do: () => void; }' is not assignable to type Doable. Object literal must specify known properties, and 'message' does not exist in type Doable". Note that the same message is given if I define the object outside of the function call, i.e.
var thing: Doable;
thing = {
private message: 'ahoy-hoy!', // error here
do: () => {
alert(this.message);
}
};
doThatThing(thing);
The same error occurs if I add "unexpected" methods as well:
doThatThing({
do: () => {
alert("ahoy hoy");
},
doSecretly: () => { // compiler error here now
alert("hi there");
}
});
I looked at the JavaScript and discovered that this within the inline object definition was being scoped to the global object:
var _this = this; // wait, no, why!?
function doThatThing(doableThing) {
doableThing.do();
}
doThatThing({
message: 'ahoy-hoy!',
do: function () {
alert(_this.message); // uses global
}
});
I tried searching for information on inline implementations of interfaces in TypeScript, but couldn't find anything speaking to this issue specifically.
I can confirm that the "fixed" compiled JS works as intended:
function doThatThing(doableThing) {
doableThing.do();
}
doThatThing({
message: 'ahoy-hoy!',
do: function () {
alert(this.message);
}
});
...and that makes sense to me, because (as far as I understand) this is implicitly calling the Object constructor, so this should be scoped to the new Object instance.
It seems like the only solution is to declare each implementation as a class implementing the interface, but that feels really regressive/heavy-handed since I'm only going to have one instance of each class. If the only contract with the called function is implementing the interface, then why can't the object contain additional members?
Sorry, this turned out longer than I intended ...in summary, I'm asking:
Why is that inline interface implementation ("anonymous class", as would be said in Java) considered invalid in TypeScript? Specifically, what does that compiler error mean, and what does it protect against?
Why is the scope-reassignment to the global object generated in the "compiled" JavaScript?
Assuming it's my error (e.g. that the compiler error is necessary for protecting against some undesirable condition), is the only solution really to explicitly declare a class in advance, like so?
interface Doable {
do() : void;
}
class DoableThingA implements Doable { // would prefer to avoid this ...
private message: string = 'ahoy-hoy';
do() {
alert(this.message);
}
}
class DoableThingB implements Doable { // ... as well as this, since there will be only one instance of each
do() {
document.getElementById("example").innerHTML = 'whatever';
}
}
function doThatThing (doableThing: Doable) {
doableThing.do();
}
var things: Array<Doable>;
things = new Array<Doable>();
things.push(new DoableThingA());
things.push(new DoableThingB());
for (var i = 0; i < things.length; i++) {
doThatThing(things[i]);
}
P.S. The compiler error only appeared when I upgraded to TS 1.6 today, although the faulty scope bug in the compiled JS occurs in both 1.6 and 1.5.
Update: François Cardinaux provided a link to this answer, which recommends using a type assertion, but this only removes the compiler error and actually causes a logic error due to improper scope:
interface Doable {
do();
}
function doThatThing (doableThing: Doable) {
doableThing.do();
}
doThatThing(<Doable>{ // assert that this object is a Doable
private message: 'ahoy-hoy!', // no more compiler error here
do: () => {
alert(this.message);
}
});
Looking at the compiled JS, this is incorrect:
var _this = this; // very wrong, and now hidden
function doThatThing(doableThing) {
doableThing.do();
}
doThatThing({
message: 'ahoy-hoy!',
do: function () {
alert(_this.message); // s/b "this.message", which works in JS (try it)
}
});
OK, I finally discovered the problem to question 2 - I was using the fat arrow => to declare the object's method here:
doThatThing(<Doable>{
private message: 'ahoy-hoy!',
do: () => { // using fat arrow: global scope replaces new object's scope
alert(this.message);
}
});
...which "sucked" the global scope into the method. The problem is fixed using the longer syntax, like so:
doThatThing(<Doable>{
private message: 'ahoy-hoy!',
do: function() { // using "regular" anonymous function syntax, "this" meaning is preserved
alert(this.message);
}
});
So in summary:
unanswered;
There was a typo in my code, and I should have been using "function()" instead of "=>"; and,
Type-asserting the object with the interface removes the compiler error.
I am developing a NodeJS module and its file size is increasing dramatically, however I have realized that I can divide my module into two separate modules. When this happens only a few functions in my second module need to use internal C++ classes of my first module. Is it possible to somehow only pass the prototype of the first module to the second one?
Example:
Module A:
Has a class called cModuleA:
class cModuleA {
//declarations
data* pointer;
}
Module B:
Has about 100 function but only one of them needs to manipulate data* pointers. It needs to return cModuleA object as well (therefore it needs a prototype of cModuleA or be aware of cModuleA implementation)
I have tried to export symbols from the first module (dllimport/dllexport in windows) but I was just wondering if there is any better option to inject dependencies at C++ level.
I found a solution to this problem and I am going to go over it in detail since probably nobody else has attempted to do such a crazy thing!
Assume you have two native node modules. Meaning that they live in separate executable files (.node). One of them is moduleA and the other one is moduleB:
ModuleA:
class cppClass
{
public:
cppClass();
~cppClass();
// C++ stuff here
}; // !class cppClass
class cppClassWrap
: public node::ObjectWrap
{
public:
// used for initializing this class for Node/v8
static void Initialize(v8::Handle<Object> target);
// internal C++ data accessor
cppClass* GetWrapped() const { return internal_; };
// internal C++ data accessor
void SetWrapped(cppClass* n) { internal_ = n; };
private:
cppClassWrap();
cppClassWrap(cppClass*);
~cppClassWrap() { if (internal_) delete internal_; };
// JS stuff here
static Persistent<Function> constructor;
// JS c'tor
static NAN_METHOD(New);
// internal C++ data
cppClass* internal_;
}; // !class cppClassWrap
//-------------------------------------------------
// JS c'tor implementation
NAN_METHOD(cppClassWrap::New)
{
NanScope();
cppClassWrap* obj;
if (args.Length() == 0)
{
obj = new cppClass();
}
// **** NOTICE THIS! ****
// This is a special case when in JS land we initialize our class like: new cppClassWrap(null)
// It constructs the object with a pointer, pointing to nothing!
else if (args[0]->IsNull())
{
obj = new cppClass(nullptr);
}
else
{
//copy constructor for the JS side
obj = new cppClassWrap(ObjectWrap::Unwrap<cppClassWrap>(args[0]->ToObject())->GetWrapped());
}
obj->Wrap(args.This());
NanReturnValue(args.This());
}
From this point on, all you need to do is to for example have Persistent handle in ModuleB to store a copy of the constructor of ModuleA's class c'tor in it. For example you can have a method called dependencies and call it in JS like:
var cppClassWrap = require("ModuleA.node").cppClassWrap;
var moduleB = require("ModuleB.node").dependencies({
"moduleA" : function() {return new cppClassWrap(null); }
});
And done! you have module injection at C++ level!
I think this has been addressed somewhere, at some point, just for the life of me I can't remember so here's my question:
I'm doing some javascript work that will be loaded into an existing application. This application has crap loads of functions available and hardly any of it is known to me except some that I want to actually use. So lets say that I know for a fact that window.srslyUsefulFunction will be available to me and I don't care much for porting this in to a typescript definition.
So the question is how do I use window.srslyUsefulFunction in my own typescript file without creating a definition for it?
Example:
class MyClass {
public MyMethod (id : string) : void {
// do something
var result = window.srslyUsefulFunction(id);
// do something (with the result)
}
}
You can add the function to the Window interface and then use it in your TypeScript program:
interface Window {
srslyUsefulFunction(id: number): void;
}
class MyClass {
doSomething() {
window.srslyUsefulFunction(1);
}
}
I have simple workaround.
In index.html
function playIntro() {
intro = new lib.intro();
onlinePlayer.contentContainer.addChild(intro);
stage.update();
}
in my Main.ts I call it like that:
private onClick(event): void {
if (window.hasOwnProperty('playIntro')) {
window['playIntro'].call();
}
}
So... if you want to call "blind" js function from global scope, just use window["foo"].call();
Check if the function exists. If it doesn't, declare it:
if(!window.hasOwnProperty('srslyUsefulFunction')
|| typeof window['srslyUsefulFunction'] !== "function"){
window['srslyUsefulFunction'] = function(){
console.log("You're only running a dummy implementation of srslyUsefulFunction here!");
};
}
Hullo! This is my first question!
I am experimenting with the module pattern promoted by Doug Crockford and others. Mostly very happy with it so far, but I am a little unsure about the best way of handling a certain inheritance pattern.
I have it boiled down to a bare bones case using cat and mammal, although my actual intention is to make objects for a tile based game in canvas.
But here is my bare bones 'animals' case using a browser alert:
var ZOO = ZOO || {};
//
ZOO.mammal = function () {
"use strict";
var voice = "squeak.mp3", // default mammal sound
utter = function () {
window.alert(this.voice);
};
//
// public interface
return {
utter: utter,
voice: voice
};
};
//
ZOO.cat = function () {
"use strict";
// hook up ancestor
var thisCat = ZOO.mammal();
thisCat.voice = "miaw.mp3";
return thisCat;
};
//
var felix = ZOO.cat();
felix.utter();
What bothers me about this approach is that I have had to make voice a public property so that cat can modify it.
What I really want is something like 'protected' visibility (from Java, ActionScript etc.), so that cat can modify voice without anyone with access to felix being able to modify it.
Is there a solution?
You can simulate protected visibility (visible to yourself, and child objects) by passing a blank object to your base "class" to serve as the repository for your protected properties. This will allow you to share properties through your inheritance chain, without making them public.
var ZOO = ZOO || {};
ZOO.mammal = function (protectedInfo) {
"use strict";
protectedInfo = protectedInfo || {};
protectedInfo.voice = "squeak.mp3";
// public interface
return {
utter: function () {
alert(protectedInfo.voice);
}
};
};
ZOO.cat = function () {
"use strict";
var protectedInfo = {};
// hook up ancestor
var thisCat = ZOO.mammal(protectedInfo);
protectedInfo.voice = "miaw.mp3";
return thisCat;
};
Here's a live demo
Sidesteping non-answer:
There are some ways to kind of get protected properties in Javascript but they aren't necessarily very idiomatic. If I were you I would first strongly consider either
Using the convention of public properties prefaced with an underscore (ex.: _voice) to denote privacy. Its very simple and is something of a standard among dynamic languages.
Seek an alternate solution without inheritance. Inheritance often complicates and couples stuff to much, hence the old "prefer composition over inheritance" mantra. Javascript has many features, like duck typing and higher order functions, that often let you avoid using inheritance in situations where you would normaly need it in Java
There is a workaround to simulate protected members, where you make public those members for a while, and then you privatise them again. I'm not a big fan of this, but it's a "solution".
I'm just quoting from this SitePoint article:
Adding Protected Members
Splitting a script into multiple modules is a common and convenient
practice. It makes a large codebase much easier to manage, and allows
for bandwidth savings to be made when modules aren’t always required.
But what if we want to share data between different modules? If we
make that data public then we’ll lose the benefits of privacy, but if
we make it private it will only be available to one module. What we
really need are shared private members, and these are known as
protected.
JavaScript doesn’t have protected members as such, but we can
effectively create them by making data temporarily public. To achieve
this, let me first introduce you to two key functions — extend and
privatise — which we’ll define as part of a utility-functions object:
var utils = {
extend : function(root, props) {
for(var key in props) {
if(props.hasOwnProperty(key)) {
root[key] = props[key];
}
} return root;
},
privatise : function(root, prop) {
var data = root[prop];
try { delete root[prop]; } catch(ex) { root[prop] = null; }
return data;
}
};
The extend function simply adds new properties to an object, while the
privatise function copies a property and then deletes the original. We
can use extend in one module to create a public reference to a private
variable, and then use privatise in another module to copy it back to
a private variable and delete the public reference.
So here’s an example of the first module which has two protected
members (including the utils object itself), and one public member. To
keep the code example short, the utility functions are just empty
shells, but they would be identical to the functions I showed you a
moment ago:
var MyModule = (function() {
var myProtectedData = 909;
var utils = {
extend : function(root, props) { },
privatise : function(root, prop) { }
};
this.myPublicData = 42;
return utils.extend(this, { myProtectedData : myProtectedData, utils : utils });
})();
You can see how we’re using a variant of the revealing module pattern,
to return not just the public members, but the protected members as
well. So at this point we have three public members:
MyModule.myProtectedData, MyModule.utils and MyModule.myPublicData.
Now here’s an example of the last module which uses the privatise
function to copy the specified public members back to private
variables, and then delete their public references:
var MyModule = (function() {
var myProtectedData = this.utils.privatise(this, 'myProtectedData');
var utils = this.utils.privatise(this, 'utils');
return this;
}).apply(MyModule);
And once that’s done the protected members are locked inside their
objects, privately available to both the modules, but no longer
available from outside them.
Note that the privatise function relies on having separate arguments
for the object and the property-key, because objects in JavaScript are
passed by reference. So root is a reference to MyModule, and when we
delete a property from it that’s specified by key, we’re deleting that
property from the referenced object.
But if it was like this:
privatise : function(root) {
var data = root;
try { delete root; } catch(ex) { root = null; } return data;
}
And called like this:
var myProtectedData = this.utils.privatise(this.myProtectedData);
Then the public members would not be deleted — the function would
simply delete the reference, not the property it refers to.
The try ... catch construct is also necessary for older IE versions,
in which delete is not supported. In that case we nullify the public
property rather than deleting it, which is obviously not the same, but
has an equivalent end result of negating the member’s public
reference.