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

Community
  • 1
  • 1
keithphw
  • 380
  • 1
  • 4
  • 14
  • 3
    Why would you want to turn the existing property into a method? –  Jul 06 '13 at 17:52
  • To Matt Johnson and delnan: Thanks, but I'm aware of that as stated in my post. I'm trying to define it as a function so I can cut-and-paste my java code into js without having to stuff around re-coding things. cheers – keithphw Jul 06 '13 at 17:53
  • 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*. –  Jul 06 '13 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*. – David Thomas Jul 06 '13 at 18:05
  • " I'm trying to define it as a function so I can cut-and-paste my java code into js without having to stuff around re-coding things." seriously ??? – cirne100 Jul 06 '13 at 18:11
  • Thank you for the tip David. But to me, code re-use and maintainability of two libs in different languages is more important. Making updates to the java version and being able to cut and paste into the js version is an advantage. I find the idiosyncracies of javascript frustrating. In my opinion, it is a poor man's java. But I appreciate your comment, just different view points. – keithphw Jul 06 '13 at 18:15
  • 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. – 1983 Jul 06 '13 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](http://javascript.crockford.com/javascript.html). You may begin to appreciate JS on its own merits. It is really nothing like Java except for the curly braces. – dodgethesteamroller Jul 06 '13 at 18:58
  • This is called language bigotry. – foundling Jan 10 '17 at 19:09

2 Answers2

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 }.

1983
  • 5,882
  • 2
  • 27
  • 39
  • 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 Jul 06 '13 at 18:02
  • 2
    @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. – 1983 Jul 06 '13 at 18:03
  • 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 – keithphw Jul 06 '13 at 18:08
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! ;)

W . S.
  • 19
  • 6