Created
November 10, 2012 05:46
-
-
Save brettz9/4050063 to your computer and use it in GitHub Desktop.
Shim to allow array-like access on "new String()" characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Add our shim to support array-like accessors on | |
String objects (i.e., those invoked with new String()) --> | |
<script src="String.js"></script> | |
<script> | |
// Regular string literals or String() invoked without 'new' will | |
// behave the same as without the shim in all browsers (i.e., | |
// accessors are not supported in IE < 9) | |
var str = 'abc'; | |
alert(str[0]); // 'a' in FF, undefined in IE < 9 | |
alert(str.slice(1)); // 'bc' | |
var str2 = String('abc'); | |
alert(str2[0]); // 'a' in FF, undefined in IE < 9 | |
alert(str2.slice(1)); // 'bc' | |
// String() with 'new' will, by using the shim, | |
// behave the same in all browsers (i.e., accessors ARE supported) | |
var str3 = new String('abc'); | |
alert(str3[0]); // 'a' | |
alert(str3.slice(1)); // 'bc' | |
// Still preserves default behavior as far as the String constructor (except that | |
// it cannot prevent iteration of the String.prototype -- though it can allow | |
// extension of the prototype before or afterward) | |
// See https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#Distinction_between_string_primitives_and_String_objects | |
var s1 = '2 + 2'; // creates a string primitive | |
var s2 = String('2 + 2'); // creates a string primitive | |
var s3 = new String('2 + 2'); // creates a String object | |
alert(typeof s1); // 'string' | |
alert(typeof s2); // 'string' (would be 'object' in IE < 9 if we uncommented return line in Str constructor) | |
alert(typeof s3); // 'object' | |
alert(eval(s1)); // number 4 | |
alert(eval(s2)); // number 4 | |
alert(eval(s3)); // "2 + 2" | |
String.prototype.strengthen = function () { | |
return '<strong>' + this + '</strong>'; | |
}; | |
alert(s3.strengthen()); // <strong>2 + 2</strong> | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
var i, p, ml, method, methods, | |
test = String('a'); | |
if (test[0]) { | |
return; | |
} | |
// Inheriting from or iterating over String.prototype is not possible, | |
// nor does it work to iterate over '' or String instance, so we hard-code | |
methods = ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', | |
'localeCompare', 'match', 'replace', 'search', 'slice', | |
'split', 'substr', 'substring', 'toLocaleLowerCase', | |
'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', | |
'trim', 'valueOf' | |
]; | |
function addStringMethods (method) { | |
return function () { | |
// Using String.prototype gives stack error in IE, so we obtain from our test instance | |
return test[method].apply(this._str, arguments); | |
}; | |
} | |
function Str (str) { | |
var i, strl; | |
if (!(this instanceof Str)) { | |
// Could uncomment the following line to allow String() invocation | |
// without the "new" keyword, but then "typeof" would not return "string" as expected | |
//return new Str(str); | |
return '' + str; | |
} | |
str = str + ''; // Ensure converted (avoid converting with String() in case line above uncommented) | |
this._str = str; | |
this.length = strl = str.length; | |
for (i = 0; i < strl; i++) { | |
this[i] = str.charAt(i); | |
} | |
} | |
for (i = 0, ml = methods.length; i < ml; i++) { | |
method = methods[i]; | |
if (test[method]) { // Only add if supported (i.e., not trim()) | |
Str.prototype[method] = addStringMethods(method); | |
} | |
} | |
// Default methods shouldn't be iteratable, but we want to grab any user-defined properties/methods | |
for (method in String.prototype) { | |
Str.prototype[method] = addStringMethods(method); | |
} | |
Str.prototype.constructor = String; | |
String = Str; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment