1

I am trying to convert java code to javascript (js), and I'm quite frustrated by how js is missing many string methods. I'm aware of js string libraries and that you can do someString.length to get a string's length. But I was pleasantly surprised to see in the top answer to this topic: How to check if a string "StartsWith" another string? That the startsWith method can be defined in my own js code file like so:

if (typeof String.prototype.startsWith != 'function') {
  String.prototype.startsWith = function (str){
    return this.indexOf(str) == 0;
  };
}

So I tried to do something similar for the length method:

if (typeof String.prototype.length != 'function') {
  String.prototype.length = function (){
    return this.length;
  };
}
var str = "a string";
alert(str.length());

But it doesn't work, I get the following error in chrome when I try to call: Uncaught TypeError: Property 'length' of object is not a function

Does anyone know why I can't create a length() function similarly to how it can be done for the startsWith(str) method explained above? Thanks, Keith

9
  • 3
    Why would you want to turn the existing property into a method? Commented Jul 6, 2013 at 17:52
  • 4
    Very bad idea. That won't fly for most code. The languages are just too different. Also note that this (if it worked to begin with) would break everyone else's code. Commented Jul 6, 2013 at 17:53
  • 4
    The first step to translating an application into another language is learning the language to which you wish to translate, not rewriting the language to be like the language you're translating from. Commented Jul 6, 2013 at 18:05
  • 2
    You can't cut-and-paste Java into JavaScript any more than you can cut-and-paste Java into C. Please ignore the fact that 'Java' is a substring of 'JavaScript'. That's unfortunate. Try calling it by its official name, ECMAScript instead. Commented Jul 6, 2013 at 18:17
  • 3
    I find the idiosyncracies of javascript frustrating. In my opinion, it is a poor man's java. I completely understand your frustration. It's typical of people coming to JS from strongly typed, classical OO languages. If you only consider the Java-like features of JS you are really programming in a poor subset of the language, though. Take a look at this article by Douglas Crawford. You may begin to appreciate JS on its own merits. It is really nothing like Java except for the curly braces. Commented Jul 6, 2013 at 18:58

2 Answers 2

9

String instances are created with an immutable length property which isn't inherited from String.prototype. So you won't be able to create a length() method for Strings.

See http://ecma-international.org/ecma-262/5.1/#sec-15.5.5

String instances inherit properties from the String prototype object and their [[Class]] internal property value is "String". String instances also have a [[PrimitiveValue]] internal property, a length property, and a set of enumerable properties with array index names.

And see http://ecma-international.org/ecma-262/5.1/#sec-15.5.5.1

Once a String object is created, this property is unchanging. It has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the pointer NagaJolkia, interesting exceprts from the spec. But I still don't understand how the fact that length is a property means that I can not access it using a length() function. cheers,
@keithphw Methods are properties too. They don't have a separate namespace if that's what you are thinking. Functions are objects in JavaScript and are stored as properties the just like any other value.
Thank you NagaJolokia, I wasn't aware of that. So when I try to define a new method called length, it clashes with the length property because they're both properties. Now I understand. Many thanks for your swift reply. Cheers, keith
0

It's simple. Just implement the prototype of object.

// Defines the name what You want
String.prototype.size = function () {
   return this.length;
}

'abc'.size ();

If You want some nice implementations, go ahead:

// Defines the name what You want
String.prototype.untilChar = function (charEnding) {
   return charEnding && this.includes (charEnding) ? this.substr (0, this.indexOf (charEnding)).length : this.length;
}

'abcdefg'.untilChar ('d'); // Returns 3
'abcdefg'.untilChar ('z'); // Returns 7

If You can't get the correct solution, don't even try with runarounds! ;)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.