why is javascript array index set by array length - javascript

Came across this code, and it had me scratching my head, and wondered is their benefits to grabbing the length to set the index.
var thisarray = new Array();
function addtoArray(int){
thisarray[thisarray.length] = int;
}
over array.push
function addtoArray(int){
thisarray.push(int)
}
Also, is there an equivalent to this php
thisarray[]

In the example you have posted, the two uses are the same. Both append a new element to the end of the array.
However, the push() method can take multiple arguments and so you can append multiple elements to the end of the array in one statement. push() then returns the new length of the array. push() is also shorter and arguably easier to read.
Another thing to consider is that if thisarray has been incorrectly defined (ie. it is not an Array object) then thisarray[thisarray.length] = int; is likely to fail silently since .length will simply be undefined. Whereas thisarray.push(int) will fail with a trappable TypeError exception.
Regarding PHP's thisarray[] (square bracket) syntax. There is nothing quite the same in JavaScript, as far as syntax goes. However, thisarray[thisarray.length] = int; performs the same action.

thisarray[thisarraylength] = int and thisarray.push(int) are identical. Arguably, the only advantage the latter has over the former is readability.
You might also find answers to this question useful: Why is array.push sometimes faster than array[n] = value?

Related

is it good to have side effect from filter method's callback [duplicate]

In the last year I've been using array methods like map and filter more often instead of the standard for loop on an array. It feels simpler to read and write, and does all the things I'm most likely going to do anyway, like create a local variable.
Often times I don't return anything though. Eslint doesn't like me very much though. According to them, they say you always need a return, otherwise its "probably a mistake"
https://eslint.org/docs/rules/array-callback-return
Why? Is just good practice? What are downsides of a return-less array method?
Been thinking on this for a while. Any insight or thoughts would be great.
Should I use array methods like map and filter, if I'm not going to return anything?
No, you should not.
Why? Is just good practice?
Yes. It is a good practice to use the appropriate iteration method for the type of iteration you are doing. There are numerous ways to iterate for a reason. Pick the appropriate mechanism.
What are downsides of a return-less array method?
Using .map() and .filter() without actually returning anything from the callback have the following downsides:
Your code is misleading. The point of .map() and .filter() is to iterate over the array and produce a new array. When a developer reads some code and sees .map() or .filter() being used, they expect that there should be a returned array. When they don't see it being done that way, they will be confused, will initially feel like they don't understand the code. If I were doing a code review on code like this, I would not approve of code like this.
Your code unnecessarily creates objects that are not used. That's just wasteful and is not a good practice. Instead, use an iteration method that does not produce an output array such as for/of, a regular for loop or .forEach().
Your code won't lint. Linters provide objections to things for a reason. Using .map() or .filter() without returning anything from the callback is, just as the linter says, "probably a programming mistake" because that is not how those functions are designed to be used and there are appropriate alternatives when you don't want a returned array.
So, if you're just trying to do an iteration without creating any resulting array, use for/of or .forEach() or some other iteration scheme that isn't specifically designed to create an output array that you don't want.
First you need to know about the difference between Map/Filter and forEach.
resuming.. forEach is mostly used when you want iterate an array with/as a procedure. check
Map and Filter are related to a callback function applied on every iteration.
The return statement of those is what is going to be evaluated, not the function By the Map/Filter function at the end. Reason why it's needed. Althought JS allows "whatever" And of course you are able to define that function what comes to our understanding as "The filter".
For Filter you can see that "true" and "false" as when the "data" is going to be filtered or not.
basically you can loop with map or forEach/for, the difference are the following:
foreach: This iterates over a list and applies some operation with side effects to each list member, this means that you are transforming THE CURRENT ARRAY you are looping.... or as noticed by #TiagoCoelho, you dont mess with the array at all, just loop thought it.
map: This iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members, this means that you will get a BRAND NEW ARRAY with the modified items and you will also have in memory your old array.
so basically it depends on what you want to do with the data inside of your array.
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
examples:
var a = [1, 2, 3, 4];
var b = [1, 2, 3, 4];
//multiply each item for 2, it will stay on the same array.
a.forEach(i => {
i = i * 2
})
//multiply the items of B for 2 but it will return a new array
var c = b.map(i => {
return i * 2
})
console.log(a); //modified reference
console.log(b); //stays the same
console.log(c); //new array

Indexing through a constant string

I was playing with a constant string in a loop from another question…
Here it is:
str = "abcd";
for (i = 0; i < 4; i++) {
console.log(str[i]);
}
… and I ended up doing that:
for (i = 0; i < 4; i++) {
console.log("abcd"[i]);
}
I didn't know this kind of coding was working before I tried!
How is this way of doing called?
Should it be avoided for any technical reason?
Thanks for any answer.
How is this way of doing called?
I'm not aware of it having any specific name. You're just using a string literal inside the loop.
Should it be avoided for any technical reason?
With a string literal it probably doesn't matter, because string literals define primitive strings (and are likely reused by the JavaScript engine, as they're immutable). But if you were creating an object every time, that would be unnecessary overhead compared with just creating it once and reusing it.
For instance, if you were doing this:
for (var i = 0; i < 4; i++) {
console.log([1, 2, 3, 4][i]);
}
That code tells the JavaScript engine to create that array each time the loop body runs, which is fast, but not instantaneous. (The JavaScript engine might be able to analyze the code and optimize it if the code were used enough that it seemed worth bothering, but that's a different topic.)
The way to tried is okay but not very useful as if you specify the string in the loop it becomes static to the loop.
It is advised to use Variable insteads of "HARDCODED" values.
All your code really does is do away with the variable and index the "array-like" object directly.
Strings are "array-like" objects. They have .length property and can be indexed just as Arrays can be. They are not however, actual arrays and don't support the full Array API. JavaScript is full of "array-like" objects and they are certainly not anything to be avoided. To the contrary, it is a great feature of the language to be able to leverage this. It's just important to know when you have an actual Array and when you have an "array-like" object, so you don't use the latter incorrectly.
So, because "abcd" is array-like, there is no reason you can't place an index right after it:
"abcd"[2]
Scott Marcus explains what's happening here well. As far as whether this should be avoided, many believe it is better to access chars in a string using chatAt() instead of bracket notation. Namely because:
Bracket notation is part of ECMAScript 5 and therefore not universally supported
The similarity to bracket notation of an array or hash object can be confusing. For instance, strings are immutable so you cannot set the value of a string at a certain index as you can with an array or hash. Using chatAt() can therefore elucidate that one should not expect this to be possible.
Source:
string.charAt(x) or string[x]?

.slice.call vs .push in javascript

One of my friends uses [].slice.call() to fill an array with matched elements.
I wonder how this works. I just know the Array.prototype.push to fill an array.
Also I have seen there is a difference in both techniques to fill an array.
So my questions are:
How does Array.prototype.slice help to fill an array?
What are the roles of Array.prototype.slice and Array.prototype.push to make objects and arrays?
Fiddle
var arr=[];
var arr=[].slice.call($('[id^=name]'));
//arr.push($('[id^=name]'))
console.log(arr)
The .slice() method of arrays returns a shallow copy of a portion of an array. It's written as a method on the Array prototype, so the array it operates on is the array in whose context it's invoked. Normally that'd be something like this:
var newArray = oldArray.slice(2, 4);
When you call the .slice() method with .call(), you can control the value of this explicitly. In your friend's code, he's passing a jQuery object as the this value. Because there are no other parameters, .slice() returns a shallow copy of the jQuery object in its entirety, as a new array. (Like some other similar methods, .slice() will work on anything that looks like an array: basically, anything that has a .length property and numerically-indexed properties of interest. A jQuery object fits that description.)
However, since jQuery already has a built-in method to return a plain array of all matched elements, your friend should not bother doing that anymore:
var plainArray = $('[id^=name]').get();
That does exactly the same thing. Using .slice() isn't wrong, but it's kind-of pointless.
How about $('[id^=name]').get()?
The [].slice.call method leverages the array-like length and numeric key properties of jQuery objects to re-use the intentionally generic methods of Array.prototype. The method Array.prototype.slice is documented by the standard to return a new Array object by performing a specific algorithm that accesses numeric-keyed properties in sequence of the this object - regardless of its type - assigning the values to sequential elements of the new Array.
I wouldn't use either approach, because jQuery has get(), which is documented to return an array of the elements matched. Why use a more obscure or less direct approach?
I does't have any specified reason for this case, but The thing i know is, .slice() also used to create another instance of an array, And here the slice add a space to its instance because it have no parameters.
Javascript is the language where you perform a Single operations in 1000's of different ways ! its depend on your choice!
But, We must have to follow the syntax that is made for particular operation.

workaround: javascript dictionary which takes objects as keys

I read a few questions and answers about javascript dictionary implementations, but they don't meet my requirements:
the dictionary must be able to take objects as keys
the values must be accessible by the []-operator
So I came up with the idea to overwrite the valueOf-method in Object.prototype, as follows:
Object.__id__ = 0;
Object.prototype.valueOf = function() {
if(!this.__id__)
this.__id__ = ++Object.__id__;
return "__id__" + this.__id__;
}
Object.prototype.toString = Object.prototype.valueOf;
//test
var x = {p1: "5"};
var y = [6];
var z = {};
z[x] = "7";
z[y] = "8";
console.log(z[x], z[y]);
I tested this with google-chrome and it seems to work well, but I'm a bit sceptical, whether this will cause some drawbacks, since it was so easy to implement.
Considering that the valueOf method is not used for other purposes in the whole code, do you think there are any disadvantages?
It's an interesting idea. I suggest my jshashtable. It meets your first requirement but not the second. I don't really see the advantage of insisting on using the square bracket property access notation: do you have a particular requirement for it?
With jshashtable, you can provide a hashing function to the Hashtable constructor. This function is passed an object to be used as a key and must return a string; you could use a function not dissimilar to what you have there, without having to touch Object.prototype.
There are some disadvantages to your idea:
Your valueOf method will show up in a for...in loop over any native object;
You have no way determining which keys should be considered equal, which is something you may want to do. Instead, all keys will be considered unique.
This won't work with host objects (i.e. objects provided by the environment, such as DOM elements)
It is an interesting question, because I had so far assumed that any object can be used as an index (but never tried with associative arrays). I don't know enough about the inner workings of JavaScript to be sure, but I'd bet that valueOf is used somewhere else by JavaScript, even if not in your code. You might run into seemingly inexplicable problems later. At least, I'd restrict myself to a new class and leave Object alone ;) Or, you explicitly call your hashing function, calling it myHash() or whatever and calling z[x.myHash()] which adds clutter but would let me, personally, sleep better ;) I can't resist thinking there's a more JavaScript-aware solution to this, so consider all of these ugly workarounds ;)
If you came upon this question looking for a JS dictionary where objects are keys look at Map Map vs Object in JavaScript

JavaScript's Statement Performance Questions

Can you guys help me determine the performance difference of each of these
statements? Which one would you use?
Making a new Array using
- var new_list = new Array(); //or
- var new_list = [];
Appending element using
- push('a')
- new_list[i]; (if i know the length)
Ternary operator or if() {} else (){}
Trying to make isodd function, which is faster
(! (is_even)) or (x%2!=0)
forEach() or normal iteration
one more
a= b = 3; or b=3; a=b;
[edit: I'm making a Math Library. So any performance hacks discussions are also welcome :) ]
Thanks for your help.
I've always assumed that since (x&1) is a bitwise operation, it would be the fastest way to check for even/odd numbers, rather than checking for the remainder of the number.
Performance characteristics for all browser (especially at the level of individual library functions) can vary dramatically, so it's difficult to give meaningful really meaningful answers to these questions.
Anyhoo, just looking at the fast js engines (so Nitro, TraceMonkey, and V8)
[ ] will be faster than new Array -- new Array turns into the following logic
cons = lookup property "Array", if it can't be found, throw an exception
Check to see if cons can be used as a constructor, if not: throw an exception
thisVal = runtime creates a new object directly
res = result of calling cons passing thisVal as the value for this -- which requires logic to distinguish JS functions from standard runtime functions (assuming standard runtime functions aren't implemented in JS, which is the normal case). In this case Array is a native constructor which will create and return a new runtime array object.
if res is undefined or null then the final result is thisVal otherwise the final result is res. In the case of calling Array a new array object will be returned and thisVal will be thrown away
[ ] just tells the JS engine to directly create a new runtime array object immediately with no additional logic. This means new Array has a large amount of additional (not very cheap) logic, and performs and extra unnecessary object allocation.
newlist[newlist.length] = ... is faster (esp. if newlist is not a sparse array), but push is sufficiently common for me to expect engine developers to put quite a bit of effort into improving performance so this could change in time.
If you have a tight enough loop there may be a very slight win to the ternary operator, but arguably that's an engine flaw in the trival case of a = b ? c : d vs if (b) a = c; else a = d
Just the function call overhead alone will dwarf the cost of more or less any JS operator, at least in the sane cases (eg. you're performing arithmetic on numbers rather than objects)
The foreach syntax isn't yet standardised but its final performane will depend on a large number of details; Often JS semantics result in efficient looking statements being less efficient -- eg. for (var i in array) ... is vastly slower than for (var i = 0; i < array.length; i++) ... as the JS semantics require in enumeration to build up a list of all properties on the object (including the prototype chain), and then checking to make sure that each property is still on the object before sending it through the loop. Oh, and the properties need to be converted from integers (in the array case anyway) into strings, which costs time and memory.
I'd suggest you code a simple script like:
for(var i = 0; i < 1000; i++){
// Test your code here.
}
You can benchmark whatever you want that way, possibly adding timing functions before and after the for statement to be more accurate.
Of course you'll need to tweak the upper limit (1000 in this example) depending on the nature of your operations - some will require more iterations, others less.
Both are native constructors probably no difference.
push is faster, it maps directly to native, where as [] is evaluative
Probably not much of a difference, but technically, they don't do the same thing, so it's not apples to apples
x%2, skips the function call which is relatively slow
I've heard, though can't find the link at the moment, that iteration is faster than the foreach, which was surprising to me.
Edit: On #5, I believe the reason is related to this, in that foreach is ordered forward, which requires the incrementor to count forward, whereas for loops are ever so infinitesimally faster when they are run backward:
for(var i=a.length;i>-1;i--) {
// do whatever
}
the above is slightly faster than:
for(var i=0;i<a.length;i++) {
// do whatever
}
As other posters suggest, I think doing some rough benchmarking is your best bet... however, I'd also note that you'll probably get very different results from different browsers, since I'm sure most of the questions you're asking come down to specific internal implementation of the language constructs rather than the language itself.
This page says push is slower.
http://dev.opera.com/articles/view/efficient-javascript/?page=2

Categories

Resources