As I google this question so one person give answer that property is faster than method and give one example of size() and length.
He said length is faster than size because length is property. Can you please let me know is it correct ? Or If you will give example then it will be great for me.
size internally calls the length
//http://code.jquery.com/jquery-latest.js
// The number of elements contained in the matched element set
size: function() {
return this.length;
},
So if you are using length then you are avoiding one extra method call. The Jquery docs says:
The .size() method is functionally equivalent to the .length property;
however, the .length property is preferred because it does not have
the overhead of a function call.
I am assuming that you want to get the length of a String or the number of elements in an Array.
size() is not a method of the Array or String objects. Thus if it exists some library or you yourself have added this method to the respective prototypes. length on the other hand is a default property and (should) exist in any JS runtime.
Unless you cannot use length, the size function will just add unneeded overhead and I would go for the property.
Check the following to links:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/prototype
If you will read length property then only time required to access an object property will be needed.
However if you will call size() then first of all a function will be called, this function will read length property internally and then return that value to the caller.
You can clearly see that you are doing the same thing in both cases. But if you call the function then it will include time for calling a function + returning that value too..
Length returns the same thing and is slightly faster according to the jQuery documentation.
Source: http://api.jquery.com/size/
Related
I am trying to return the value under the key 'str' in an Object but I am having trouble accessing the value.
This is what is returned in the console:
Currently I am using a map function to go over the array and just return the _str value like so:
let idx = currentArray.map(function(x) {
return x._id._str;
});
However it is still returning the value as an object. How can I get just the value of the _str key?
Here is the full array without specifying the id field. This is what is returned if you jsut return 'x' in the map function.
You've clarified that the screenshot is of x._id. So to access _str, you'd use x._id[0]._str: The _str property is in the object referenced by the 0 property (the first entry in the array x._id refers to).
Note that in general, _-prefixed properties are meant not to be accessed by code outside the code responsible for the objects in question. You don't seem to be responsible for them, so accessing those properties is likely to make your code rely on undocumented properties that may change in the next "dot" release of whatever lib you're using. It's just convention, but it's a very common convention.
If you right click on the property, most browser consoles offer the ability to copy property path.
Based on this SO post and the docs, it appears that you can probably use x._id.str.
If I understand correctly, you are receiving the str value but it is an object instead of the string literal. In other words, you are getting _str: "598..." instead of "598....". A possible solution would be to use the mongo javascript function to convert the str value to a string.
In your case, I think something like return x._id.str; may work as _id is a MongoID.ObjectID.
I've also linked the documentation below for reference.
https://docs.mongodb.com/manual/reference/method/ObjectId/
Here's a relevant SO answer as well: Convert ObjectID (Mongodb) to String in JavaScript
I think you should write x[_id]._str because _id is one of the array objects.
I’m learning javascript and trying to write code that sorts a list, removing elements if they meet certain criteria.
I found this snippet that seems promising but don't have a clue how it works so I can adapt it to my needs:
list = document.getElementById("raffles-list").children; // Get a list of all open raffles on page
list = [].filter.call(list, function(j) {
if (j.getAttribute("style") === "") {
return true;
} else {
return false;
}
});
Can you guys help me learn by explaining what this code block does?
It's getting all the children of the "raffles-list" element, then returning a filtered list of those that contain an empty "style" attribute.
The first line is pretty self-evident - it just retrieves the children from the element with id "raffles-list".
The second line is a little more complicated; it's taking advantage of two things: that [], which is an empty array, is really just an object with various methods/properties on it, and that the logic on the right hand side of the equals sign needs to be evaluated before "list" gets the new value.
Uses a blank array in order to call the "filter" method
Tells the filter to use list as the array to filter, and uses function(j) to do the filtering, where j is the item in the list being tested
If the item has a style attribute that is empty, i.e. has no style applied, it returns true.
Edit:
As per OP comment, [].filter is a prototype, so essentially an object which has various properties just like everything else. In this case filter is a method - see here. Normally you just specify an anonymous function/method that does the testing, however the author here has used the .call in order to specify an arbitrary object to do the testing on. It appears this is already built into the standard filter method, so I don't know why they did it this way.
Array like objects are some of javascript objects which are similar to arrays but with differences for example they don't implement array prototypes. If you want to achieve benefits of array over them (for example like question filter children of an element )you can do it this way:
Array.prototype.functionName.call(arrayLikeObject, [arg1, [arg2 ...]]);
Here in question array like is html element collection; and it takes items without any styling.
list is assigned a collection of elements that are children of the raffles-list element
list is then reassigned by filtering its elements as follows
an empty array is filtered by calling it with the parameter list and a callback function. The formal parameters for call are this (which is the list) and optionally further objects (in this case a callback function)
The callback function receives a formal parameter j and is called for each element
If the element's value for the style attribute is empty the element is retained in the array. Otherwise it is discarded.
At the end list should contain all elements that don't have a value for its style attribute
I am currently using the Chrome console to do some debugging for a Greasemonkey script.
From the console I run var opp = document.querySelectorAll('a[class="F-reset"]'); and it works as expected.
But if I try to remove the first element with opp.splice(0,1) I get the following error
Uncaught TypeError: opp.splice is not a function
at <anonymous>:2:5
at Object.InjectedScript._evaluateOn (<anonymous>:905:140)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:838:34)
at Object.InjectedScript.evaluate (<anonymous>:694:21)
If I try to run opp[0].indexOf("a"), i get the same thing.
How would I fix this?
Yes, this is because the result of querySelectorAll is a node list, not an array. You can apply the slice method of Array to a node list, however:
Array.prototype.slice.call(op, 0, 1);
This works more or less as expected, because a NodeList "quacks" in just the way slice expects, i.e. it contains elements indexed sequentially. However, you should be wary of using this in general; it is much safer to simply iterate over the NodeList.
querySelectorAll returns a NodeList. This is similar to an array (it has a .length property and you can index it with []), but it's not actually an array, and doesn't have most of the array methods. If you want to use array methods on an array-like object, you have to call the method explicitly:
Array.prototype.splice.call(opp, 0, 1);
or:
[].splice.call(opp, 0, 1);
However, another difference between arrays and NodeLists is that you can't modify NodeList in place, which .splice tries to do; you can only read them like arrays. You should just use .slice() to extract the parts you want. Or convert the NodeList to an array first, and then operate on that. See
Fastest way to convert JavaScript NodeList to Array?
querySelector/All returns a NodeList not an array, so those functions are not available.
You can use call to use those array methods though
[].splice.call(opp,0,1);
The first argument is the execution context that the function will use, all other arguments are the arguments that will be passed to the function
Function call reference
First,
splice is a method of Arrays, inherited through Array.prototype, although it is intentionally generic so can be called on other Arraylike objects
querySelectorAll returns a non-live NodeList, this is not an Array and does not share any inheritance with Array, meaning you can't simply access Array methods through it
A function can be invoked with a custom this via call or apply
splice needs to be able to assign on it's this, which will fail for a NodeList as you will get the following TypeError: Cannot set property length of #<NodeList> which has only a getter
Other intentionally generic Array methods which only read from this will work on a NodeList, e.g. slice, map, indexOf, forEach, filter, some, every, etc..
Now we are in a position to do something,
Convert the NodeList to an Array and store this reference, i.e. with Array.prototype.slice
Perform your splice on this object instead
So,
var opp = document.querySelectorAll('a[class="F-reset"]'); // NodeList
oop = Array.prototype.slice.call(oop); // Array
// ...
oop.splice(0, 1);
In JavaScript why doesn't the keyword length require ()? It seems all the other functions such as splice(), shift() require parenthesis.
We can only speculate why it was made a plain property and not a method.
However, the .length is a constant value for each string/array, it does not modify anything when being computed (it's not "executed" like a method), and it would not take any parameters anyway. Therefore it qualified well as an accessor property.
Also, assigning to .length allows us to control the size of the array (shrinking/expanding it). It's more convenient (or at least: idiomatic) to use the existing property as a setter than to introduce an extra .setLength(…) method.
Length is not a method. It is a property. See MDN
When calling properties you do not need parentheses.
A property is something that an object "knows" about it self. An array or a string in javascript knows its length. A method is something that needs to be calculated.
Length could have been a method on javascript strings if javascript had really needed to count the letters each time you want the length.
When get a value from a property you can make an assumption that it is quicker to get its value than it would be getting a value from a method call. (Although this is not always the case)
splice and shift are operations that calculate something based on the current state and/or their parameters. Furthermore they change the array. length in contrast is constant for a given array, no operation need to retrieve it. There is no need to make it a function.
length is a property, not a function. therefore it doesn't need brackets().
The length property is calculated and updated when the objects changes, while calling a function length() would calculate this value upon each single call.
Adding to my comment
The JavaScript array length property returns the number of elements in an array.
It is always one greater than the largest index value of the array
One can if required( not advisable) change the length property
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length
The EcmaScript language specification, designed the length to be a property.
Read Here
Let's say you have a website of 100 pages and there is a div with an id of #unique-div that only appears in page-5.html, but not in the other 99 pages and to be extra simple with the example you have a JS file that is loaded on all pages, and inside it there is this:
var uniqueDiv = $('#unique-div');
uniqueDiv.addClass('random-class');
does that have any negative impact in any possible way (for instance, performance)? Would it better to do a length check first?
var uniqueDiv = $('#unique-div');
if ( uniqueDiv.length ) {
uniqueDiv.addClass('random-class');
}
If so, why?
Or what about if you are chaining objects like this:
var uniqueDiv = $('#unique-div');
someVar.add(moreVars).add(uniqueDiv).addClass('random-class');
If the object doesn't exist, what happens?
I tried looking this up, but I have always wondered this.
It is the responsibility of ANY jQuery method to have a "proper" behavior whether there are 0, 1 or more than 1 DOM objects in the current jQuery object that they are called on. So, as long as you aren't using some broken jQuery plug-in methods, you do not have to test the length before calling a method and this includes situations where you are using chaining.
So, in your case this would be perfectly fine, even if you had no idea whether #unique-div actually existed:
$('#unique-div').addClass('random-class');
If the div didn't exist, then the .addClass() method would just do nothing.
Note: that some methods that retrieve a value such as .val() are coded to only operate on the first DOM element in a jQuery object and you will have to check with an individual method like that what they are coded to return if there are no DOM objects in the jQuery object. For example, .val() will return undefined when there are no DOM objects in the jQuery object.
There might be some infinitesimal amount of performance saving, but it's really negligible. There are probably going to be plenty of times in your code you'll do a for-loop through an array, acknowledging the length might be zero.
JQuery objects always have some size to them, and all methods I know of (ie, addClass) are equipped for empty sets, so I don't see any issue with skipping the length check.