What is Javascript FunctionList? - javascript

I was playing an online game named untrusted, which is played by writing code.
There are some syntax that I've never seen before and couldn't find one the web. Can someone explain this to me?
functionList['movePlayerToExit'] = function () {
map.writeStatus("Permission denied.");
}
functionList['pleaseMovePlayerToExit'] = function () {
map.writeStatus("I don't think so.");
}
functionList['movePlayerToExitDamnit'] = function () {
map.writeStatus("So, how 'bout them <LOCAL SPORTS TEAM>?");
}
Please explain the what is functionList, thank you!
And for those who are familiar with this game, please don't spoil, thank you again!

Most people would write
functionList['movePlayerToExit'] = ...
as
functionList.movePlayerToExit = ...
It's just ordinary JavaScript object property reference syntax. Since those strings would be valid if used as identifiers, there's no need to use the [ ] syntax.
Thus, if it's not clear, functionList is an object. Exactly what it means in the code you're looking at, I can't say. It looks like some sort of dispatch object, so that an operation code like "movePlayerToExit" can be looked up and the corresponding function invoked:
var actionCode = getActionCode(totallyMakingThisUp);
if (functionList[actionCode] != null)
functionList[actionCode]();
Note that in that made-up example, it is necessary to use [ ] to access the properties of functionList, because the property name is stored in a variable.

It is probably just an object where functions are assigned to keys (properties):
var obj = {};
obj["foo"] = function () { ... };
obj["bar"] = function () { ... };
Is the same as:
var obj = {
"foo": function () { ... },
"bar": function () { ... }
};
Just like a map.
However, it is possible it is an instance of a class which overrides the square bracket operator such as Array, Map, WeakMap, etc. But that doesn't really define a different behaviour.

Related

how do I make a function including a dot

I want to make a function called "lib.hello" is that valid syntax and if not how do I do it?
here us my code function lib.hello(){ console.log("hello") }
function lib.hello(){
console.log("hello")
}
You can do it this way
function yourClass() {
}
yourClass.prototype.dotFunction = function() { return 'hello'; };
console.log(new yourClass().dotFunction());
first you must create an object next you do it same as bellow.
let Obj = {
a:1,
childMethod:(param)=>{console.log(param)}
}
Obj.childMethod("test")
Or you can do it by bellow code:
function yourClass() {
}
yourClass.prototype.childMethod = function(parameter) { console.log(parameter); };
var a = new yourClass();
a.childMethod("test");
//or you can do it same as follow
new yourClass().childMethod("test2")
Why are you asking to do this? This seems like either an XY Problem, or an exercise in theory.
As other answers have alluded to, you can make a class named lib with a method named hello, but that's not quite the same as a function named lib.hello.
Here's another variation:
let a = {
'lib.hello' : function() {
console.log('hello');
}
}
a['lib.hello']()
Technically this is an anonymous function, not a function named lib.hello, but it's kind of what you're asking for because it's associated with the key lib.hello.

Is it possible to have multiple dynamic method names in a class?

I'm reading through the ES6 class information on Babel.js's documentation and noticed that it says that objects can now have dynamic property names:
var obj = {
...
// Computed (dynamic) property names
[ "prop_" + (() => 42)() ]: 42
};
This seems like it would be useful in classes as well. Is it possible to do something similar in an ES6 class without doing it in a constructor, i.e.:
class Foo {
[ "read" + (...)(['format1', 'format2']) ] {
// my format reading function
}
}
rather than doing something like this in the constructor:
class Foo {
constructor(opts) {
let formats = ['format1', 'format2'];
let self = this;
formats.forEach(function(format) {
self["read" + format] = function() {
// my format reading function
}
})
}
}
In other words, I want to be able to take some array, such as ['format1', 'format2'] and create two methods, readformat1 and readformat2, in the class dynamically, without using the constructor. Is this possible?
Yes, it's possible, you only missed the required () for the method signature:
class Foo {
[ "read" + ((format) => format)(myFormat) ]() {
// my format reading function // ^--- this what missed
}
}
Babel repl: long and ugly url here
As of your updated question: it's not possible (at least I'm not aware of it). So you can create methods with names resolved in runtime, but you cannot create N methods from the array using that syntax.
I found this question in a first Google link, so should give another helpful answer :)
ES6 classes is mostly just a syntactic sugar, so you still can use prototypes and do something like
class Foo { ... }
let formats = [ 'format1', 'format2' ];
formats.forEach(function(format) {
Foo.prototype['read' + format] = function () { ... }
});
I've not found a better way.

Unable to create a closure for a function inside of object instance to send to another object

I have this :
objectA .....
objectB = function (){
value:1,
do_things: function (param1, param2, option) {bla bla},
connect : function (dest){
My_objectA.set_external_do_thing = function ?????????
}
}
Then I have :
MY_objectA = new objetA();
MY_objectB = new objetB();
MY_objectB.connect(My_objectA);
I'd like to write the right code to send a do_things function to ObjectA and then call it from there. do_things uses local variables param1 and param2. I need to set them but I can't.
By now I have a lot of undefined messages I can't solve.
Any help would be appreciated.
As #Bergi right said you made some mistakes, I fix them and tried to implement a sample from what I understand is your doubt... take a look...
Assume that you have two objects:
var husband = {
spentFactor: 1,
buyThings: function () {
console.log('bla bla');
},
buyOtherThings: function (param1) {
console.log("Final Cost: " + (param1*this.spentFactor));
}
};
var wife = {
spentFactor: 10,
buyThings: function () {
console.log('bla bla');
}
};
then if you want to use buyOtherThings() method from husband object, but you know we man have a different spent factor:
husband.buyOtherThings(20);
husband.buyOtherThings.apply(wife, [20]);
The apply() method is the key, every function descend from a Function object and you inherits this by default. This method permit that you change the this from a object, so we can reuse a function from a different object.
play around this code here

JavaScript : Create new object of a custom class based on an existing one (adding methods to it)

I use the iOS UI Automation framework to make sure my iPhone app rocks.
Everybody who uses this framework would tell you that it's great, but that it's lacking a lot of structure.
So I have to deal with instances of UIAWindow, which represent different screens of my app. To be more object-oriented, I'd like to have a specific class for each screen, so I could add specific methods, like
myScreen1.tapDoneButton();
var total = myScreen2.getNumberOfElements();
For the moment, I'm able to achieve this by passing the instances of UIAWindow to functions that will add the appropriate methods, like this :
function makeMainScreen(actualScreen)
{
actualScreen.constructor.prototype.getAddButton = function() {
return this.buttons()["add button"];
};
actualScreen.constructor.prototype.tapAddButton = function() {
this.getAddButton().tap();
};
// Add any desired method...
return actualScreen;
}
It works fine, I use it like this :
var mainScreen = makeMainScreen(app.mainWindow());
mainScreen.tapAddButton();
But that doesn't seem object-oriented enough, I would like to create real objects, using the new and this keywords, so I'd have a declaration like this :
function MainScreen(actualScreen){
// This line doesn't work : because 'this' is immutable
this = actualScreen;
this.tapAddButton = function(){
this.getAddButton().tap();
}
//...
}
And I'd use it like this :
var mainScreen = new MainScreen(app.mainWindow());
mainScreen.tapAddButton();
I thought I could save the actualScreen as a property of the object (Like in Grace Shao's answer below), and call all the methods on it, but I'd like keep the original UIAWindow methods.
Does anybody know how to do this?
Or perhaps what I'm trying to achieve doesn't make sense, in which case I'd be happy to know.
If I understand correctly, you could try the following:
function MainScreen(actualScreen){
this.screen = actualScreen;
}
MainScreen.prototype.tapAddButton = function () {
this.screen.getAddButton().tap();
};
MainScreen.prototype.getScreen = function () {
return this.screen;
};
//...
var mainScreen = new MainScreen(app.mainWindow());
mainScreen.tapAddButton();
You are correct that you cannot assign anything to this. You could also define the methods inside the constructor MainScreen, but they would be considered privileged members.
function MainScreen(actualScreen){
this.screen = actualScreen;
this.tapAddButton = function () {
this.screen.getAddButton().tap();
};
}
If you dont want them to be privileged members, it is better to define them outside the constructor. Otherwise, the members will be initialized over and over again everytime when you instantiate a new object.
Updated:
You could also wrappers for the methods of screen inside the constructor as below.
var prop;
for (prop in actualScreen) {
if (typeof actualScreen[prop] !== 'Function') {
continue;
}
this[prop] = function () {
return actualScreen[prop].apply(actualScreen, arguments);
};
}

Returning the method of a function

In the code below, I've got two objects declared, with one object inheriting the properties and functions of another.
I want to use the super variable to call the methods of the object I inherited from. When I trace out itemEditor, I can see the function and it's methods correctly. When I try to access the method of itemEditor, it returns undefined.
What am I doing wrong? Is there a better way to do this?
var myObject = {
itemEditor : function (vars) {
this.editItem = function () {
alert("Editing Item");
}
},
recurringItemEditor : function (vars) {
myObject .itemEditor.apply(this, [vars]);
this.prototype = myObject.itemEditor.prototype;
var super = myObject.itemEditor
this.editItem = function () {
console.log("fn.recurringItemEditor.editItem");
console.log(super);
console.log(super.editItem);
super.editItem.call(this);
}
}
Your code seems a little confused. On the one hand myObject.itemEditor is a constructor and therefore a function (myObject.itemEditor.apply(this, [vars])), and on the other you treat it like an object with a prototype (this.prototype = myObject.itemEditor.prototype;).
That's not even considering that super is a reserved keyword.
Your example may be simplifying something you are trying to do, but I don't see why you don't just use the usual prototype inheritance. That way you can still have a method in your local instance and call the prototype one within it if you want e.g.
recurringItemEditor : function (vars) {
this.prototype = new myObject.itemEditor(vars);
this.editItem = function () {
console.log("fn.recurringItemEditor.editItem");
console.log(this.prototype);
console.log(this.prototype.editItem);
this.prototype.editItem.call(this);
}
}
I used your advice and it works well now. In regards to treating it like a function and an object, myObject .itemEditor.apply(this, [vars]); was still required in order for the object to inherit the properties of itemEditor. I should have made that clear in the original code. If there's a better way to do this, let me know.
var myObject = {
itemEditor : function (vars) {
var myVars = vars + "foo";
this.editItem = function () {
alert(myVars);
}
},
recurringItemEditor : function (vars) {
myObject .itemEditor.apply(this, [vars]);
this.prototype = new myObject.itemEditor(vars);
this.editItem = function () {
console.log("fn.recurringItemEditor.editItem");
console.log(this.prototype);
console.log(this.prototype.editItem);
this.prototype.editItem.call(this);
}
}
}

Categories

Resources