As for the question which event you should use for this: use the input event, and fall back to keyup/keydown in older browsers.
Here’s an example, DOM0-style:
someElement.oninput = function() {
this.onkeydown = null;
// Your code goes here
};
someElement.onkeydown = function() {
// Your code goes here
};
The other question is how to count the number of characters in the string. Depending on your definition of “character”, all answers posted so far are incorrect. The string.length answer is only reliable when you’re certain that only BMP Unicode symbols will be entered. For example, 'a'.length == 1, as you’d expect.
However, for supplementary (non-BMP) symbols, things are a bit different. For example, '𝌆'.length == 2, even though there’s only one Unicode symbol there. This is because JavaScript exposes UCS-2 code units as “characters”.
Luckily, it’s still possible to count the number of Unicode symbols in a JavaScript string through some hackery. You could use Punycode.js’s utility functions to convert between UCS-2 strings and Unicode code points for this:
// `String.length` replacement that only counts full Unicode characters
punycode.ucs2.decode('a').length; // 1
punycode.ucs2.decode('𝌆').length; // 1 (note that `'𝌆'.length == 2`!)
P.S. I just noticed the counter script that Stack Overflow uses gets this wrong. Try entering 𝌆, and you’ll see that it (incorrectly) counts as two characters.
Basic JavaScript - Find the Length of a String
How does String.length work in JavaScript? - Stack Overflow
How to get length of string in javascript without using native length method - Stack Overflow
javascript - Create a string of variable length, filled with a repeated character - Stack Overflow
Videos
As for the question which event you should use for this: use the input event, and fall back to keyup/keydown in older browsers.
Here’s an example, DOM0-style:
someElement.oninput = function() {
this.onkeydown = null;
// Your code goes here
};
someElement.onkeydown = function() {
// Your code goes here
};
The other question is how to count the number of characters in the string. Depending on your definition of “character”, all answers posted so far are incorrect. The string.length answer is only reliable when you’re certain that only BMP Unicode symbols will be entered. For example, 'a'.length == 1, as you’d expect.
However, for supplementary (non-BMP) symbols, things are a bit different. For example, '𝌆'.length == 2, even though there’s only one Unicode symbol there. This is because JavaScript exposes UCS-2 code units as “characters”.
Luckily, it’s still possible to count the number of Unicode symbols in a JavaScript string through some hackery. You could use Punycode.js’s utility functions to convert between UCS-2 strings and Unicode code points for this:
// `String.length` replacement that only counts full Unicode characters
punycode.ucs2.decode('a').length; // 1
punycode.ucs2.decode('𝌆').length; // 1 (note that `'𝌆'.length == 2`!)
P.S. I just noticed the counter script that Stack Overflow uses gets this wrong. Try entering 𝌆, and you’ll see that it (incorrectly) counts as two characters.
UPDATE: Since I wrote this, the input event has gotten a decent level of support. It is still not 100% in IE9, so you will have to wait a bit until IE9 is fully phased out. In light of my answer to this question, however, input is more than a decent replacement for the method I've presented, so I recommend switching.
Use keyup event
var inp = document.getElementById('myinput');
var chars = document.getElementById('chars');
inp.onkeyup = function() {
chars.innerHTML = inp.value.length;
}
<input id="myinput"><span id="chars">0</span>
EDIT:
Just a note for those that suggest keydown. That won't work. The keydown fires before character is added to the input box or textarea, so the length of the value would be wrong (one step behind). Therefore, the only solution that works is keyup, which fires after the character is added.
A string is immutable in JavaScript.
a += "somestring" doesn't change the length of a string but makes a new string.
This means there is no "new length", but the length is just part of the definition of the string (more precisely it is stored in the same structure in implementations).
Regarding
for(i=0;i<a.length;i++){ // did you forget the 'var' keyword ?
a not so uncommon practice (if you don't change a) was to optimize it as
for (var i=0, l=a.length; i<l; i++)
in order to avoid the reading of the length but if you compare the performances with modern engines, you'll see this doesn't make the code any faster now.
What you must remember : querying the length of a string is fast because there is no computation. What's a little less fast is building strings (for example with concatenation).
Strings are a primitive type. At least that's what the documentation says. But we can access the length of the string as if we are accessing the property of an object(with the dot notation). Which indicates it's an object, Right?
Turns out, whenever we make a call from the string primitive to some property using the dot notation (for example, say length), the Js engine will take this primitive string and wrap it into an equivalent wrapper object, which is a String object. And then, the .length on that String object returns the length.
Interesting thing to note here is, that when we do something like this, our string still stays the same primitive string during all of this. And a temporary object is created to make our string operation work. Once the required property is fetched, this temporary object is deleted from the memory.
Hope this gives some high level understanding.
You can loop over the string, testing to see whether there is a non-undefined value at each index (as soon as you get an undefined value you've run past the end of the string):
function strLength(s) {
var length = 0;
while (s[length] !== undefined)
length++;
return length;
}
console.log(strLength("Hello")); // 5
console.log(strLength("")); // 0
(I'm assuming that if you're not allowed to use the native string .length property that you probably shouldn't use the array .length property either with str.split("").length...)
Given that this is a practice problem, I suspect the OP may not want ES6/ES2015, but, just in case that's an option, and/or for whoever else is looking at this, here's a concise modern approach:
const str = "Hello world!";
console.log([...str].reduce(a => a+1, 0));
(When I posted this, no other answer had proposed this solution. However, I had missed the fact that @MarkoGrešak had essentially proposed this exact solution in a comment to another question.)
The best way to do this (that I've seen) is
var str = new Array(len + 1).join( character );
That creates an array with the given length, and then joins it with the given string to repeat. The .join() function honors the array length regardless of whether the elements have values assigned, and undefined values are rendered as empty strings.
You have to add 1 to the desired length because the separator string goes between the array elements.
Give this a try :P
s = '#'.repeat(10)
document.body.innerHTML = s
(V8 developer here.)
I can see several issues here that can be looked at separately:
1. From a language specification perspective, is something a method or a property?
Intuitively, the distinction is: if you write a function call like obj.method(), then it's a method; if you write obj.property (no ()), then it's a property.
Of course in JavaScript, you could also say that everything is a property, and in case the current value of the property is a function, then that makes it a method. So obj.method gets you a reference to that function, and obj.method() gets and immediately calls it:
Copyvar obj = {};
obj.foo = function() { console.log("function called"); return 42; }
var x = obj.foo(); // A method!
var func = obj.foo; // A property!
x = func(); // A call!
obj.foo = 42;
obj.foo(); // A TypeError!
2. When it looks like a property access, is it always a direct read/write from/to memory, or might some function get executed under the hood?
The latter. JavaScript itself even provides this capability to objects you can create:
Copyvar obj = {};
Object.defineProperty(obj, "property", {
get: function() { console.log("getter was called"); return 42; },
set: function(x) { console.log("setter was called"); }
});
// *Looks* like a pair of property accesses, but will call getter and setter:
obj.property = obj.property + 1;
The key is that users of this obj don't have to care that getters/setters are involved, to them .property looks like a property. This is of course very much intentional: implementation details of obj are abstracted away; you could modify the part of the code that sets up obj and its .property from a plain property to a getter/setter pair or vice versa without having to worry about updating other parts of the code that read/write it.
Some built-in objects rely on this trick, the most common example is arrays' .length: while it's specified to be a property with certain "magic" behavior, the most straightforward way for engines to implement this is to use a getter/setter pair under the hood, where in particular the setter does the work of truncating any extra array elements if you set the length to a smaller value than before.
3. So what does "abc".length do in V8?
It reads a property directly from memory. All strings in V8 always have a length field internally. As commenters have pointed out, JavaScript strings are immutable, so the internal length field is written only once (when the string is created), and then becomes a read-only property.
Of course this is an internal implementation detail. Hypothetically, an engine could use a "C-style" string format internally, and then it would have to use a strlen()-like function to determine a string's length when needed. However, on a managed heap, being able to quickly determine each object's size is generally important for performance, so I'd be surprised if an engine actually made this choice. "Pascal-style" strings, where the length is stored explicitly, are more suitable for JavaScript and similar garbage-collected languages.
So, in particular, I'd say it's fair to assume that reading myString.length in JavaScript is always a very fast operation regardless of the string's length, because it does not iterate the string.
4. What about String.length?
Well, this doesn't have anything to do with strings or their lengths :-)
String is a function (e.g. you can call String(123) to get "123"), and all functions have a length property describing their number of formal parameters:
Copyfunction two_params(a, b) { }
console.log(two_params.length); // 2
As for whether that's a "simple property" or a getter under the hood: there's no reason to assume that it's not a simple property, but there's also no reason to assume that engines can't internally do whatever they want (so long as there's no observable functional difference) if they think it increases performance or saves memory or simplifies things or improves some other metric they care about :-)
(And engines can and do make use of this freedom, for various forms of "lazy"/on-demand computation, caching, optimization -- there are plenty of internal function calls that you probably wouldn't expect, and on the flip side what you "clearly see" as a function call in the JS source might (or might not!) get inlined or otherwise optimized away. The details change over time, and across different engines.)
Length is not a method, it is a property. It doesn't actually do anything but return the length of an array, a string, or the number of parameters expected by a function. When you use .length, you are just asking the JavaScript interpreter to return a variable stored within an object; you are not calling a method.
Also, note that the String.length property gives the actual number of code units in a string, rather than a literal character count. One code unit is 16 bits as defined by UTF-16 (used by JavaScript). However, some special characters use 32 bits which means that in a string containing one of these characters the String.length property might give you a higher character count than the literal number of characters.
Link:- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
And also one fact length work very different with string.length from Array.length
Copylet myString = "bluebells";
myString.length = 4;
console.log(myString); //bluebells
console.log(myString.length); //9
//--
let myArr = [5,6,8,2,4,7];
myArr.length = 2;
console.log(myArr); //[5, 6]
console.log(myArr.length); //2