Javascript Get Prototype Function Name - javascript

Disclaimer: This code was written by another developer, previously on the project and I can't change it - I'm not allowed too.
What I'm trying to do is get the name of the parent(?) function within this.foobar() from BaseDialog.
Is it possible?
var BaseDialog = new function () {
this.foobar = function () {
// get the prototype function name that called me? E.g DialogOne
}
}
DialogOne.prototype = BaseDialog;
function DialogOne() {
this.foobar();
}
DialogTwo.prototype = BaseDialog;
function DialogTwo() {
this.foobar();
}

let callerName = arguments.callee.caller.name.toString();
console.log("caller is " + callerName );

Related

Can not use class in a function as a parameter (JScript)

I am trying to do a small JavaScript Lab. In the lab, first I created an Animal object :
function Animal(species, nature) {
this.species = species;
this.nature = nature;
var preys = new Array();
Animal.prototype.getSpecies = function() {
return species;
}
Animal.prototype.getNature = function() {
return nature;
}
Animal.prototype.getPreys = function () {
return preys;
}
Animal.prototype.setNature = function (newNature) {
nature = newNature;
}
Animal.prototype.setSpecies = function (newSpecies) {
species = newSpecies;
}
Animal.prototype.setPrey = function (newPreys) {
preys = newPreys;
}
}
Then, I created a World object which will basically store a number of animal object and separate them according to their nature.
/// <reference path="Animal.js" />
function World() {
var animals = new Array();
animals.push(new Animal("Wolf", "Carnivore"));
animals.push(new Animal("Crocodile", "Carnivore"));
animals.push(new Animal("Sheep", "Omnivore"));
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores());
}
function getOmnivores(animal) {
}
}
In my getOmnivors function, I can not use the Animal class as a variable. It is a little bit complicated for me cause I am new in JavaScript and regardless of their types we are using var keyword (Or not using in some places such as parameters in functions).
What did I do wrong and how can I fix it? I could not reach the Animal class in my private function getOmnivores. I think program does not understand that it is the class called Animal
I hope I explained well. Have a nice day!
EDIT
Error picture :
Animal is the Class name, you don't need it there. When using filter each element of the array is automatically passed on to the callback function as the first parameter of that function.
Since each element of the array is an instance of the class Animal you can use it straight away.
Also, the syntax {ClassName}.Prototype.{functionName} should not be used within that same Class, because by the time the interpreter reaches that line the Animal Class has not yet been defined. That syntax is used on already existing and defined classes. Use this.{functionName} instead.
function Animal(species, nature) {
this.species = species;
this.nature = nature;
this.preys = new Array();
this.getSpecies = function() {
return this.species;
}
this.getNature = function() {
return this.nature;
}
this.getPreys = function () {
return this.preys;
}
this.setNature = function (newNature) {
this.nature = newNature;
}
this.setSpecies = function (newSpecies) {
this.species = newSpecies;
}
this.setPrey = function (newPreys) {
this.preys = newPreys;
}
}
function World() {
var animals = new Array();
animals.push(new Animal("Wolf", "Carnivore"));
animals.push(new Animal("Crocodile", "Carnivore"));
animals.push(new Animal("Sheep", "Omnivore"));
this.getOmnivores = function () {
return animals.filter(this.filterOmnivores);
}
this.filterOmnivores= function(animal) {
return animal.getNature()=='Omnivore';
}
}
myworld = new World();
console.log(myworld.getOmnivores());
A working fiddle at https://jsfiddle.net/47dyg1q9/
The filter method takes a function as a paramter.
You must provide the function but in your code you are instantly calling the function:
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores());
}
Remove the parentheses to provide just the function without calling it, or insert an anonymous function:
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores);
}
// or
World.prototype.getOmnivores = function () {
return animals.filter(function (animal) {
return animal.nature === "omnivore";
});
}
You need to pass the function as an argument, not what it returns.
return animals.filter(isOmnivore);
And isOmnivore becomes
function isOmnivore(animal) {
animal.nature == 'Omnivore';
}

ext js - create custom function with passed parameters

Just a warning, this is my first ExtJS project.
I have two stores loaded from a webserver successfully.
Store containing positions
Store containing marketData
I've created a third store to hold all of my results.
Now I want to go through each position, find the market data record associated, and run a simple calculation.
I have done this successfully all on the event of clicking a button, but I want to separate out the function of doing the actual calculation... passing in parameters.
For now just to get the concept working I created a function called 'sayHello', but I am getting an error stating... ReferenceError: sayHello is not defined.
Can someone point out what I am doing wrong to create this custom function?
Thanks!
my controller...
Ext.define('ExtApplication1.view.clientdetails.clientdetailsController', {
extend: 'Ext.app.ViewController',
alias: 'controller.clientdetails-clientdetails',
onClickCalculate: function () {
console.log('calculation button was hit');
var targetGrid = Ext.getCmp('positionsGridID');
var positionsStore = targetGrid.store;
var marketDataGrid = Ext.getCmp('marketsGridID');
var marketDataStore = marketDataGrid.store;
var calculatedPositionsDataGrid = Ext.getCmp('calculatedPositionsGridID');
var calculatedPositionsDataStore = calculatedPositionsDataGrid.store;
console.log(calculatedPositionsDataStore);
positionsStore.each(function (record) {
console.log('the details for the whole position');
console.log(record);
var bbSymbol = record.get('BBSymbol');
var singleRecord;
marketDataStore.each(function (record) {
var cycleBBSymbol = record.get('BBSymbol');
if (cycleBBSymbol === bbSymbol){
singleRecord = record;
return false;
}
});
console.log('position I am evaluateing is ' + bbSymbol);
console.log('market data found for ' + singleRecord.get('BBSymbol'));
console.log(singleRecord);
//debugger;
var lastPrice = singleRecord.get('Last_Price');
var settle = singleRecord.get('Px_Settle');
var qty = record.get('Quantity');
var marketName = record.get('Description');
var pnl = (lastPrice - settle) * qty;
console.log(pnl);
calculatedPositionsDataStore.add({
BBSymbol: bbSymbol,
Description: marketName,
Quantity: qty,
CalcPLSett: pnl
});
sayHello(singleRecord);
}, this);
},
sayHello: function (singleRecord) {
alert('hello');
alert(singleRecord);
}
});
You get this error because you're out of the scope of the ViewController.
In
positionsStore.each(function (record) { ...}
You are in the store scope, but the sayHello function is in the ViewController scope.
Assign the ViewController's scope to a variable, should solve your problem:
onClickCalculate: function () {
console.log('calculation button was hit');
var me = this; //NEW LINE
var targetGrid = Ext.getCmp('positionsGridID');
var positionsStore = targetGrid.store;
And then use it in the positionsStore.each function :
me.sayHello(singleRecord)

OO Javascript Calling method from another method of same object

I'm having trouble calling a method from within another method of the same object.
Any help on what I may be missing, or what to look for, would be greatly appreciated.
var IceCream = function (flavor) {
this.tub = 100;
this.flavor = flavor;
};
IceCream.prototype = {
scoop : function () {
this.updateInventory; alert("scooping");
},
updateInventory : function () {
this.tub --;
alert(this.tub);
}
};
var vanilla = new IceCream("vanilla");
vanilla.scoop();
Convert this
this.updateInventory;
to this
this.updateInventory();
DEMO

Custom object 'game' doesn't have specified method

I'm trying to call a method cardSelection() from a function game() but instead I'm getting an error report which throws back to me the whole function with a "has no method cardSelection()" The idea is to access the method through the click of a button, which HTML tag is as follows:
<img id="PlayerCard0" class="card" src="images/Cards/Mario.png" alt="Mario" title="Mario" onclick="game.cardSelection('PlayerCard0')">
I'm not posting the whole Javascript as I believe this to be the case of a mere declaration error, anyhow, game() and cardSelection() were declared as follows:
function game()
{
...
this.cardSelection = function(card)
{
var cardElem = document.getElementById(card);
var id = cardElem.getAttribute("id");
var call = document.getElementById("call");
var select = function(card)
{
var found = 0;
for (var card = 0, totalCards = 5; card < totalCards; card++)
{
if (document.getElementById("PlayerCard" + card + "selected"))
{found++}
}
if (found == 0)
{
call.setAttribute("onclick", "changeHand()");
call.childNodes[0].nodeValue = "Change";
}
if (found < 3)
{
id += "selected"
setAttributes(cardElem,
{
"id" : id,
"style": "position: relative; top: 1em;",
"onclick" : "cardSelection('" + id + "')"
});
}
else { return; }
}
var unselect = function (card)
{
cardElem.removeAttribute("style");
id = id.replace("selected","");
setAttributes(cardElem,
{
"id" : id,
"onclick" : "cardSelection('" + id + "')"
});
var cardNumber = 0;
var found = false;
while (cardNumber < 5 && !found)
{
if (document.getElementById("playerCard" + cardNumber + "selected"))
{found = true;}
cardNumber++;
}
if (!found)
{
call.setAttribute("onclick", "compareHands()");
call.childNodes[0].nodeValue = "Hold";
}
}
if (id.indexOf("selected") >= 0){unselect(card);}
else {select(card);}
}
...
}
How game() is called:
window.onload = function openingScreen()
{
var startGame = document.createElement("a");
startGame.setAttribute("onclick", "game()");
startGame.appendChild(document.createTextNode("Play"));
window.table = document.getElementById("table");
table.appendChild(startGame);
}
The problem you are experiencing is the result of confusion about Objects/Classes/Instances in javascript.
The critical point for you on this issue is the difference between new game() and game();
var foo = new game()
tells the JS engine to create a new object
point that object's Prototype (not prototype) at game's prototype
and then invoke the function game, but for the sake of the body of that function this will refer to the created object.
If the function doesn't return an object, assign our created object to foo (otherwise assign the function's return value to foo
Inside the body of your game function, you have this.cardSelection = function (....
If you simply invoke game as a function, so just game(), without the new keyword, this inside the body of the function will be the window object! So you'll add cardSelection to the window object.
Also importantly: game.cardSelection() is looking for a function named cardSelection as a property on the function game.
Here's an example of using that style that would work:
var foo = function () {
//do interesting stuff
}
foo.bar = function () {
//do interesting stuff related to foo
}
foo.bar();
What you seem to be expecting would need to be written this way:
var game = function () {
this.cardSelection = function () {
//perform card selection!
}
}
var aGame = new game();
aGame.cardSelection();
Or, if cardSelection does not need access to any private properties of the game, it could be written more efficiently as
var game = function () {
//setup the game
};
game.prototype.cardSelection = function () {
//perform card selection
};
var aGame = new game();
aGame.cardSelection();

Deep nesting functions in JavaScript

I cannot find an proper example for the love of my life on how to do this or even if this is possible. Based on my pieced together understanding from fragments of exmaples, I have come up with the following structure
var t = function()
{
this.nestedOne = function()
{
this.nest = function()
{
alert("here");
}
}
}
t.nestedOne.nest();
However this is not working (obviously). I would greatly appreciate if someone could point me in the right direction!
That is simply done with:
var t = {
nestedOne: {
nest: function() {
alert('here');
}
}
};
Your code otherwise doesn't make sense. this inside function doesn't refer to the function itself, it refers to the object context that the function is invoked in. And you are not even invoking the functions in your code.
If I say obj.func() then this inside func will be obj for that call. So assigning this.asd = true will assign true to that object's "asd" property.
If you wanted to do a nested class, it looks very different:
ClassA = (function() {
function ClassA() {
}
ClassA.prototype.method1 = function() {
};
function ClassB() {
}
ClassB.prototype.method1 = function() {
};
return ClassA;
}())
only ClassA can now make instances of ClassB. This should achieve same goals as nested classes in java.
See http://jsfiddle.net/CstUH/
function t(){
function f(){
this.nest = function()
{
alert("here");
}
}
this.nestedOne = new f();
}
var myt=new t();
myt.nestedOne.nest()
Edit 1:
You can also use
new t().nestedOne.nest()
instead of
var myt=new t();
myt.nestedOne.nest()
(http://jsfiddle.net/CstUH/1/)
Edit 2:
Or even more condensed:
function t(){
this.nestedOne = new function(){
this.nest = function(){
alert("here");
}
}
}
new t().nestedOne.nest()
http://jsfiddle.net/CstUH/2/
In JS functions are prime class objects, and you can access them directly in the code [i.e. without using reflection or so].
The code you put inside t body would be performed when actually executing t:
t();
You wrote t.nestedOne,nest(), but t has no nestedOne property - you should do like this:
var t = {
nestedOne : {
nest : function()
{
alert("here");
}
}
};
t.nestedOne.nest(); ​
I advice you to have a trip on John Resig's Learning Advanced JavaScript tutorial, it was very enlightening for me.
A simple callback handler I wrote today as an example of how I do deep nesting. I apologize if it's not the bees knees when it comes to code style, it made the concept a little clearer for me.
function test () {
this.that = this;
this.root = this;
this.jCallback = new Array(new Array()); // 2d
this.jCallbackCount = -1;
this.str = "hello";
// Callback handler...
this.command = {
that : this, // let's keep a reference to who's above us on the food chain
root : this.root, // takes us back to the main object
// add : function() { var that = this; console.log(that.that.str); },
add : function(targetFnc, newFunc) {
var that = this;
var home = that.that; // pretty much root but left in as an example of chain traversal.
var root = this.root; // useful for climbing back up the function chain
// console.log(that.that.str);
home.jCallbackCount++;
// target, addon, active
home.jCallback[home.jCallback.length] = { 'targetFunc' : targetFnc, 'newFunc' : newFunc, 'active' : true, 'id': home.jCallbackCount};
console.log('cbacklength: ' + home.jCallback.length);
console.log('added callback targetFunction:[' + targetFnc + ']');
return home.jCallbackCount; // if we want to delete this later...
},
run : function(targetFnc) {
var that = this;
var home = that.that;
console.log('running callback check for: ' + targetFnc + ' There is : ' + (home.jCallbackCount + 1) + 'in queue.');
console.log('length of callbacks is ' + home.jCallback.length);
for(i=0;i < home.jCallback.length - 1;i++)
{
console.log('checking array for a matching callback [' + targetFnc + ']...');
console.log('current item: ' + home.jCallback[i]['targetFunc'] );
if( home.jCallback[i]['targetFunc'] == targetFnc )
{
// matched!
home.jCallback[i]['newFunc']();
}
// console.log(that.that.jCallback[i].targetFunction);
}
}
};
}
test.prototype = {
say : function () {
var that = this;
console.log('inside');
// that.command('doSay');
that.command.run('doSay');
console.log(that.str);
}
} // end proto
// BEGIN TESTING **************************************************************************
// BEGIN TESTING **************************************************************************
// BEGIN TESTING **************************************************************************
var testing = new test();
testing.command.add('doSay', function () { console.log('213123123'); } );
testing.command.add('doSay', function () { console.log('12sad31'); } );
testing.command.add('doSay', function () { console.log('asdascccc'); } );
testing.say();
live:
http://jsfiddle.net/Ps5Uf/
note: to view console output, just open inspector in chrome and click on the "console" tab.

Categories