Pass vars to other method javascript - javascript

I want to pass var "firstWord" with saved value in it from one method to another.
var obj = {
getWords: function () {
var words = [];
$('input').each(function () {
words.push($(this).val());
});
var firstWord = words[0],
secondWord = words[1],
thirdWord = words[2];
},
pushWords: function () {
Array.prototype.insert = function (index, item) {
this.splice(index, 0, item);
};
var fruits = ["Banana", "Orange", "Apple", "Mango"],
randomPosition = (Math.floor(Math.random() * (5 - 2 + 1)) + 1);
fruits.insert(randomPosition, firstWord);
$('body').append(fruits);
}
};
Probably my code is wrong a bit, but is there any possibility to do that in this case?

If you declare a varible with the var keyword, it's a only available in the function. Leave it out and you'll have a global variable, which you can access from other functions as well. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var)

One way it to pass one function's value to the other, like:
function one(){
var var1 = "hello";
two(var1);
}
function two(x){
alert(x);
}
This should print "hello" for you.
The other way is to declare your firstWord as a global variable.

Try to return the array like below,
getWords: function () {
var words = [];
$('input').each(function () {
words.push($(this).val());
});
return words;
},
and in push words
pushWords: function () {
var arr = this.getWords();
................
................
................
fruits.insert(randomPosition, arr[0]);
}
$('body').append(fruits);
since var firstword,secondword and thirdword are only accessible inside the getwords function you must try to return it. And don't forget to validate the
return value before you use it. Hope it helps..
See example here https://jsfiddle.net/xz0ofkjx/

So make it a property of the object.
var obj = {
_words : [],
setWords : function () {
this._words = ["hello","world"];
},
pushWords : function () {
this._words.push("foo");
},
readWords : function () {
console.log(this._words);
}
}
obj.readWords();
obj.setWords();
obj.readWords();
obj.pushWords();
obj.readWords();

Related

How to loop an object returned by a function in another function in JS?

i've a problem in js. I've a function for example:
function robePersos() {
var persos = {"player" : "data"};
return persos;
}
and then i've another function which call robePersos() like this:
function test() {
var d = robePersos();
for(var k in d) {
console.log(k)
}
}
But nothing happens. Why ?
function robePersos() {
var persos = {
"player": "data"
};
return persos;
}
function test() {
var d = robePersos();
for (var k in d) {
console.log(k)
}
}
test();
EDIT
The first snippet works. So, here is my real function:
function robePersos() {
var persos = {};
$.get({
url : 'url',
success : function(data) {
var text = $(data).find("div[menu='perso'] a"); //.clone().children().remove().end().text();
$(text).each(function(){
perso_name = $(this).text();
perso_link = $(this).attr('href');
persos[perso_name] = perso_link;
});
}
});
for(var k in persos) {
console.log(persos[k]);
}
}
robePersos();
If I replace the loop by only console.log(persos) it works but the loop return nothing. Why ?
If you want to print both Key and Value, use the following small change in your code. Your code is printing just the keys.
function robePersos() {
var persos = {
"player": "data",
"anotherPlayer": "anotherData"
};
return persos;
}
function test() {
var d = robePersos();
for (var k in d) {
console.log(k, "-" ,d[k]); // change made here. It prints both.
}
}
test();
Try whith Object.keys()
function test() {
var d = Object.keys(robePersos());
for (var k in d) {
console.log(k, "-" ,d[k]); // change made here. It prints both.
}
}
Object.keys returns an array whose elements are strings corresponding to the enumerable properties found directly in the object. The order of the properties is the same as that provided when manually iterating over the properties of the object.
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/keys

Random select array with remove items (jQuery)

I am trying to find a way to get values from an array of random way without repeating them, I found the following solution:
var letters = ["A", "B", "C"];
var getRandom = (function(array) {
var notGivenItems = array.map(function(el) {
return el;
});
var getIndex = function() {
return Math.floor(Math.random() * notGivenItems.length);
};
return function() {
if (notGivenItems.length === 0) {
return;
}
return notGivenItems.splice(getIndex(), 1)[0];
};
})(letters);
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
If I print the console.log() 4 times, at last, the array appears as undefined, and that's precisely what I need. However, I need (function () {... don't be fired automatically, because the value that comes via AJAX. So, should be something like:
function selec() {
var getRandom = (function(array) {
var notGivenItems = array.map(function(el) {
return el;
});
var getIndex = function() {
return Math.floor(Math.random() * notGivenItems.length);
};
return function() {
if (notGivenItems.length === 0) {
return;
}
return notGivenItems.splice(getIndex(), 1)[0];
};
})(letters);
return getRandom();
}
console.log(selec());
But then, the function continues printing values continuously, without return undefined.
I hope I have understood your problem.. if yes, was really easy. Check this fiddle
var letters = ["A", "B", "C"];
function getRandom(array){
var notGivenItems = array.map(function(el){
return el;
});
var getIndex=function(){
return Math.floor(Math.random() * notGivenItems.length)
};
if (notGivenItems.length === 0)
return;
return array.splice(getIndex(), 1)[0];
}
console.log(getRandom(letters));
console.log(getRandom(letters));
console.log(getRandom(letters));
console.log(getRandom(letters));
What's happening is that every time you call selec(), it is re-creating the getRandom function.
What you need to do is define getRandom outside of the selec() function scope.
You can do it at the same level:
var getRandom = (function(array) { ... })(letters);
var selec = function() { return getRandom; };
or you can create a closure to protect getRandom from naming conflicts:
var selec = (function() {
var getRandom = (function(array) { ... })(letters);
return function() { return getRandom; };
})();

Simplify the code by using cycle function

I have multiply functions which are using the same cycle code and i'm wondering is it possible to simplify the code by having one cycle function so i could execute the code just by calling wanted function names.
Now:
for(var i=0;i<all;i++){ someFunction(i) }
Need:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
name(i);
}
}
I tried to do this by using "window" and i get no error but the function is not executed.
var MyLines = new lineGroup();
MyLines.createLines(); // works
MyLines.addSpeed(); // doesn't work
var lineGroup = function(){
this.lAmount = 5,
this.lines = [],
this.createLines = function (){
for(var i=0,all=this.lAmount;i<all;i++){
this.lines[i] = new line();
}
},
this.addSpeed = function (){
// no error, but it's not executing addSpeed function
// if i write here a normal cycle like in createLines function
// it's working ok
this.linesCycle("addSpeed");
},
this.linesCycle = function(callFunction){
for(var i=0,all=this.lAmount;i<all;i++){
window['lineGroup.lines['+i+'].'+callFunction+'()'];
}
}
}
var line = function (){
this.addSpeed = function (){
console.log("works");
}
}
window['lineGroup.lines['+i+'].'+callFunction+'()'];
literally tries to access a property that starts with lineGroups.lines[0]. Such a property would only exist if you explicitly did window['lineGroups.lines[0]'] = ... which I'm sure you didn't.
There is no need to involve window at all. Just access the object's line property:
this.lines[i][callFunction]();
i get no error but the function is not executed.
Accessing a non-existing property doesn't generate errors. Example:
window[';dghfodstf0ap9sdufgpas9df']
This tries to access the property ;dghfodstf0ap9sdufgpas9df, but since it doesn't exist, this will result in undefined. Since nothing is done with the return value, no change can be observed.
Without a name space use:
window["functionName"](arguments);
SO wrap it up and use it thus:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
window[name](i);;
}
}
With a namespace, include that:
window["Namespace"]["myfunction"](i);
Note that this is likely a bit of overkill but using a function to make a class object (you can google the makeClass and why it is/could be useful) you can create instances of the object.
// makeClass - By Hubert Kauker (MIT Licensed)
// original by John Resig (MIT Licensed).
function makeClass() {
var isInternal;
return function (args) {
if (this instanceof arguments.callee) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
var instance = new arguments.callee(arguments);
isInternal = false;
return instance;
}
};
}
var line = function () {
this.addSpeed = function () {
console.log("works");
};
};
var LineGroup = makeClass();
LineGroup.prototype.init = function (lineNumber) {
this.lAmount = lineNumber?lineNumber:5,
this.lines = [],
this.createLines = function (mything) {
console.log(mything);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i] = new line();
}
},
this.addSpeed = function () {
console.log("here");
this.linesCycle("addSpeed");
},
this.linesCycle = function (callFunction) {
console.log("called:" + callFunction);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i][callFunction]();
}
};
};
var myLines = LineGroup();
myLines.createLines("createlines");
myLines.addSpeed();
//now add a new instance with 3 "lines"
var newLines = LineGroup(3);
newLines.createLines("createlines2")
console.log("addspeed is a:" + typeof newLines.addSpeed);
console.log("line count"+newLines.lAmount );
newLines.addSpeed();

JavaScript: Subsititute ForEach and callback in anonymous function

function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
});
return result;
}
I have above code. How to alter it, in order to let the anonymous function run only over the first element in SheetNames? (or alternatively alter sth else in order to achieve the same result).
I got this so far, I am not sure it is correct.
...snip
var tmpArray = workbook.SheetNames.slice(0);
tmpArray.forEach(function(sheetName) {
...snip
One way is what you've mentioned, but .slice(0) returns the whole array, so use .slice(0,1) for only the first item:
var tmpArray = workbook.SheetNames.slice(0, 1);
tmpArray.forEach(function(sheetName) { /* ... */ })
But if you only want to process the first item you can cancel the forEach() and the anonymous()
totally:
function to_json(workbook) {
var result = {},
sheetName = workbook.SheetNames[0],
roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if(roa.length > 0) result[sheetName] = roa;
return result;
}

Why are my properties assigning incorrectly?

I created an ObservablePropertyList which is supposed to execute a callback when a property changes. The implementation is:
function ObservablePropertyList(nameCallbackCollection) {
var propertyList = {};
for (var index in nameCallbackCollection) {
var private_value = {};
propertyList["get_" + index] = function () { return private_value; }
propertyList["set_" + index] = function (value) {
// Set the value
private_value = value;
// Invoke the callback
nameCallbackCollection[index](value);
}
}
return propertyList;
}
And here's a quick test demonstration:
var boundProperties = BoundPropertyList({
TheTime: function (value) {
$('#thetime').text(value);
},
TheDate: function (value) {
$('#thedate').text(value);
}
});
var number = 0;
setInterval(function () {
boundProperties.set_TheTime(new Date());
boundProperties.set_TheDate(number++);
}, 500);
For some reason though, the properties are not being assigned correctly or something. That is, calling set_TheTime for some reason executes the callback for set_TheDate, almost as though it were binding everything to only the last item in the list. I can't for the life of me figure out what I'm doing wrong.
When using loops like that you need to wrap it in an enclosure
function ObservablePropertyList(nameCallbackCollection) {
var propertyList = {};
for (var index in nameCallbackCollection) {
(function(target){
var private_value = {};
propertyList["get_" + index] = function () { return private_value; }
propertyList["set_" + index] = function (value) {
// Set the value
private_value = value;
// Invoke the callback
target(value);
}
})(nameCallbackCollection[index]);
}
return propertyList;
}
You need to create a closure in order for each iteration of the for loop to have its own private_variable object. Otherwise, each iteration just overwrites the previous (since private_variable is hoisted to the top of its scope). I'd set it up like this:
var ObservablePropertyList = (function () {
"use strict";
var handleAccess = function (propList, key, callback) {
var privValue = {};
propList["get_" + key] = function () {
return privValue;
};
propList["set_" + key] = function (value) {
// Set the value
privValue = value;
// Invoke the callback
callback(value);
};
};
return function (coll) {
var propertyList = {}, index;
for (index in coll) {
handleAccess(propertyList, index, coll[index]);
}
return propertyList;
};
}());
var boundProperties = ObservablePropertyList({
TheTime: function (value) {
$('#thetime').text(value);
},
TheDate: function (value) {
$('#thedate').text(value);
}
}), number = 0;
setInterval(function () {
boundProperties.set_TheTime(new Date());
boundProperties.set_TheDate(number++);
}, 500);
DEMO: http://jsfiddle.net/PXHDT/

Categories

Resources