How to use javascript variable in Web worker thread - javascript

I need to update my javascript array in Web worker thread.
I cannot accces my javascript array in Web worker thread.
My code is :
self.onmessage = function(event) {
var array = new Uint8Array(event.data);
var sum = 0;
var temparray = new Array();
for(var list = 0; list < array.length; list++ ){
var temp = myMethod(array[list]); //some operation
availableArray.push(temp);
}
self.postMessage("success");
}
I am getting this error:
availableArrayis undefined
availableArray.push(temp);

You define 2 variables that are arrays (or array-like objects): var array = new Uint8Array and var temparray = new Array, but then in the loop you use a variable that isn't declared anywhere availableArray, I suspect you want to change that variable to temparray.
The error message makes perfect sense: availableArray is not defined anywhere. You're using it as an array, and invoking the push method on it. However, JS, by default, creates a new variable for you whenever you use a var that hasn't been declared. The default value for a non-initialized variable is, of course, undefined. undefined doesn't have a push method, hence the error.
However, just a slight remark, though: in JS new Array is actually discouraged. Best use the array literal notation:
var temparray = [];
It's shorter and safer.

Related

If I pass an array into a JS function it doesn't seem to modify that array. Shouldn't it be passed by reference?

This Javascript function inside my class doesn't seem to modify the array that it's passed to it by reference:
this.filterEqualCities(this.birthCitiesNames, this.birthCitiesPositions);
filterEqualCities: function(citiesNames, citiesPos) {
var tempNamesArray = [];
var tempPosArray = [];
for(var i=0; i<citiesNames.length; i++) {
var name = citiesNames[i];
name = name.split(',')[0];
if(tempNamesArray.indexOf(name) == -1) {
tempNamesArray.push(name);
tempPosArray.push(citiesPos[i]);
}
}
citiesNames = [];
citiesPos = [];
for(var i=0; i<tempNamesArray.length; i++) {
citiesNames.push(tempNamesArray[i]);
citiesPos.push(tempPosArray[i]);
}
}
When you do:
citiesNames = [];
citiesPos = [];
the variables are no longer references to the original arrays that were passed in, now they're references to these two empty arrays.
If you want to clear out the original arrays, you can simply set their lengths:
citiesNames.length = 0;
citiesPos.length = 0;
To expand a bit upon #Barmar's excellent answer - the issue is that arrays and other objects are not really "passed by reference" in Javascript, even though it seems that way a lot of the time, and it's often described that way. They're passed by value, like all other variables - but that "value" is itself a "reference" to an actual value stored in memory, not to another variable itself.
So if you were to modify citiesNames, say by pushing a new element onto it, that would be reflected outside the function - because you'd be modifying that shared value to which both citiesNames variables (local and global) are references to.
But when you do citiesNames=[], you're taking the citiesNames local variable and reassigning it to a completely new value, and there's no way your other citiesNames variable can know about that.
This behaviour isn't unique to Javascript. Python certainly behaves the same way (and perhaps others too that I'm not as familiar with).

JavaScript security issue

I wanna know how the following function set 'this' element and fetch the array cell out? please.
//my secure code
var priv = ['item-0','item-1'];
var api = {push: function(x){priv.push(x)}}
api.store = function(i,x){priv[i] = x}
//the attaker script
var result;
api.store('push',function(){result = this[0]});
api.push();
//the result is cell 0 of private array
//how?
//if i change the 'push' parameter then the result is empty!
document.write(result)
What happens is that api.store('push',function(){result = this[0]}); overrides the push method of the priv array. That means that after this line pushis no longer the push method that javascript natively provides but the attackers custom function, which is function(){result = this[0]}. Now, when you call api.push() it calls priv.push(x) which was overridden. Since push is called on an object, this is bound to the object, which is priv (more on that in the MDN article on this). Therefore, result = this[0] is equal to result = priv[0] and result will contain the first array entry.

array of custom object in javascript - eliminate empty occurrence

I have a custom object that I would like to create an array of. When creating my array it creates an occurrence with empty properties, I understand why, but I would like to avoid this. I realize I could just delete the occurrence with the empty properties, but is there a better way?
function FileToPassBack(path, originalFileName, modifiedDate, newFilename) {
if (!(this instanceof FileToPassBack)) {
return new FileToPassBack(namepath, originalFileName, modifiedDate, newFilename);
}
this.Path = path;
this.OriginalFileName = originalFileName;
this.ModifiedDate = modifiedDate;
this.NewFileName = newFilename;
}
function PostSelectedItems() {
var allFilesToPassBack = new Array(new FileToPassBack());
$('#fileNamesTable').find('tbody>tr:visible')
.each(function (index, element) {
var row = $(this);
if (row.find('input[type="checkbox"]').is(':checked'))
{
var path = row.find('.pathTDClass').html();
var originalFileName = row.find('.originalFileNameTDClass').html();
var modifiedDate = row.find('.modifiedDateTDClass').html();
var newFileName = row.find('input[class="newFileNameTDClass"]').val();
var currentFileToAdd = new FileToPassBack(path, originalFileName, modifiedDate, newFileName)
allFilesToPassBack.push(currentFileToAdd);
}
});
//post path, original file name, modified date, new file name
var objectAsJSON = JSON.stringify(allFilesToPassBack);
}
I am new to JS, so excuse me if I am way off track.
new Array(number)
Creating a new array with a number will initialize it with a certain number of empty elements:
var a = new Array(5);
// a = ['','','','',''];
thus when you push it will add a new entry
a.push("a");
// a = ['','','','','', 'a'];
The best practice is not to use new Array, instead use [] syntax as it is more performant.
var allFilesToPassBack = [];
JSON Stringify
although it works, you need to be aware that you are stringify-ing an array not a JSON in your example code.
Update
why [] is more performant than new Array() and considered a best practice.
When you create an array using
var a = [];
You're telling the interpreter to create a new runtime array. No extra processing necessary at all. Done.
If you use:
var a = new Array();
You're telling the interpreter, I want to call the constructor "Array" and generate an object. It then looks up through your execution context to find the constructor to call, and calls it, creating your array.
why its a best practice?
The new Array() doesn't add anything new compared to the literal syntax, it only wraps the array with an object wrapper that is not needed, only adding overhead of calling the Array constructor and creating an object wrapper around the array.
additionally defining a function Array() {} in the code, new Array() will start creating new instances from this function instead of creating an array, its an edge case, but if you need an array, just declare it with [].
You never need to use new Object() in JavaScript. Use the object
literal {} instead. Similarly, don’t use new Array(), use the array
literal [] instead. Arrays in JavaScript work nothing like the arrays
in Java, and use of the Java-like syntax will confuse you.
Do not use new Number, new String, or new Boolean. These forms produce
unnecessary object wrappers. Just use simple literals instead.
http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/
There are ton of sources, but i'll keep it minimal for this update. new was introduced to the language as it is "familiar" to other languages, as a prototypal language, the new syntax is useless and wrong, instead the language should have Object.create. but thats a different topic, you can read more about it from experts like Kyle Simpson or Douglas Crockford.
I think, though am unsure what your actual problem is, that you are calling var allFilesToPassBack = new Array(new FileToPassBack()); to initialize your array? You don't need to do that.
Try replacing that line with this instead.
var allFilesToPassBack = []
That will init an empty array than you can then pushto in your jquery each loop.

Objects in Javascript Arrays Mysteriously Linked Together

I have the following code.When I access w[1][0], I want only the object at that one location to be changed. However, all the objects change instead. I'm assuming this is because at some level, they are all pointing to the same object. How would I fix this?
var createArray = function(dim,init){//takes an array of dimensions and the initial value of each element
if(dim.length > 0){
var x = new Array();
for(var i = 0; i < dim[0]; i++)
x[i] = createArray(dim.slice(1),init)
return x;
}
return init;
}
var w = createArray([2,2],{top: false,left: false});
console.log(w);
w[1][0].left = true;
console.log(w);
In JavaScript, objects are passed by a reference, not by value. That means that if you pass the same object to a few variables, they all point to the same place in memory. This is why your init object is being changed everywhere.
To prevent this, you need to clone the object before assigning it to your variables. One of the simplest built-in methods is to use JSON, like this:
var copy = JSON.parse(JSON.stringify(original));
So in your case that would be it:
x[i] = createArray(dim.slice(1), JSON.parse(JSON.stringify(init)));
w[1][0].left = true;
This line is changing the only instance of the object. See, this line:
var w = createArray([2,2],{top: false,left: false});
is the only line in your code that creates a new object (of the type you're interested in) via the {} literal there. All other set operations (newVar = init) only copy a reference to that same object.
That sounds annoying, but it has a lot of good uses in code. To fix it, you'll want to create a copy each time, to replace the final line of createArray
var myCopy = {};
for (var key in origObject) {
if (origObject.hasOwnProperty(key)) {
myCopy[key] = origObject[key];
}
}
return myCopy;
Be warned - this is a "shallow copy", so it will only copy the top-level properties, and any objects a level deep will still be references. Many JavaScript libraries have functions to create deep copies for you.

Whats the neatets way to declare two arrays on two keys in an object in javascript?

This is how I do it now. It feels like a hazzle...
var broken_posts = new Object();
broken_posts.empty = new Array();
broken_posts.one = new Array();
var broken_posts = { empty: [], one: [] };
var broken_posts = {
empty: [],
one: []
};
The answers by Andru and Thilo are both correct, but perhaps some information on why is in order:
Avoid direct calls to the Array constructor: it's confusing and misleading. var a = new Array(5); returns [undefined,undefined,undefined,undefined,undefined], whereas var b = new Array('5'); returns ['5']. Or even var c = new Array(5,5); => [5,5].
Same applies for the direct object constructor. There's really no reason to create an object calling the basic object constructor. The only times you should use the keyword new is when creating a date object, or calling a self-made constructor function (and even in that case, there's no real need for the new keyword, there are alternative design patterns). Using the object literal {} is more common, allows for direct assignment of properties (and even methods). Besides, It's so much easier to create your objects in a JIT sort of way. Not only does it require less lines of code, with correct use of closures, or just for the one call, an object can get GC'ed once you're finished with it.
function iWantAnObject(obj)
{
if (obj instanceof Object)
{
return true;
}
return false;
}//function returns, obj is GC'ed
iWantAnObject({just:'some',rand:'Object',withA:function(){console.log('a method';}});
As opposed to this scenario:
var tempObj = new Object();
tempObj.just = 'some';//etc...
//etc...
iWantAnObjct(tempObj);
//tempObj isn't yet GC'ed
In the last example chances are: you accidentally create global variables, have various objects in memory that are no longer required, and, last but not least: isn't very in tune with the prototypal nature of JS.
I would prefer to use CoffeeScript instead.
Then you can do it this way:
broken_posts =
empty: []
one: []

Categories

Resources