Funciones de string — Referencia de SSJS en Marketing Cloud
Las operaciones de string disponibles en MC SSJS — métodos JavaScript nativos (el subset ES5 que SpiderMonkey 1.7 soporta) más los helpers de Platform.Function para formateo y stringificación. Lo que es seguro, lo que falta, y lo que tenés que polyfillear.
El manejo de strings en SSJS es mayormente JavaScript plano, pero solo el subset era ES5 que SpiderMonkey 1.7 entiende. No hay String.prototype.trim confiable, no hay template literals, no hay String.prototype.padStart / padEnd, no hay String.prototype.includes. El operador + concatena como esperarías (con coerción implícita a String(), incluyendo para null y undefined), y Platform.Function.Format cubre los casos de formateo que el lenguaje no.
Sintaxis oficial
Los métodos String nativos soportados (SpiderMonkey 1.7):
Platform.Load("Core", "1.1.5");
var email = " German.Medina@Example.COM ";
// Largo, acceso a caracteres
email.length; // → 31
email.charAt(2); // → "G" (después de los espacios iniciales)
email.charCodeAt(0); // → 32 (código del caracter espacio)
// Búsqueda
email.indexOf("@"); // → 16 (o -1 si no se encuentra, NO 0)
email.lastIndexOf("."); // → 28
// Nota: no hay .includes() — usá indexOf() > -1 en su lugar
// Slice / substring (3 formas distintas con diferencias sutiles)
email.slice(2, 16); // → "German.Medina@" (start, end-exclusivo)
email.substring(2, 16); // → "German.Medina@" (igual; negativos se vuelven 0)
email.substr(2, 14); // → "German.Medina@" (start, length — deprecated pero soportado)
// Case
email.toLowerCase(); // → " german.medina@example.com "
email.toUpperCase(); // → " GERMAN.MEDINA@EXAMPLE.COM "
// Replace
email.replace("@", "[at]"); // primera ocurrencia solamente
email.replace(/\./g, "_"); // regex, flag /g para todas
email.replace(/^\s+|\s+$/g, ""); // trim casero
// Split, concat
"a,b,c".split(","); // → ["a", "b", "c"]
"hello".concat(" ", "world"); // → "hello world" (raramente usado; preferí +)
// Pattern matching
email.match(/(\w+)@(\w+)/); // → array de match con groups
email.search(/\d+/); // → -1 (no hay dígitos en este email)Los helpers de Platform para formateo:
// Format — printf-like con args posicionales ({0}, {1}, ...)
Platform.Function.Format("Hola, {0} ({1})", ["German", "AR"]);
// → "Hola, German (AR)"
// FormatNumber — formateo de números locale-aware
Platform.Function.FormatNumber(1234567.89, "N2", "en-US");
// → "1,234,567.89"
Platform.Function.FormatNumber(1234567.89, "C", "es-AR");
// → "$ 1.234.567,89"
// FormatDate — formateo de fechas locale-aware (devuelve string)
Platform.Function.FormatDate(Now(), "yyyy-MM-dd", "en-US");
// → "2026-05-08"
// String() y (''+x) — stringificación explícita
String(42); // → "42"
String(null); // → "null"
String(undefined); // → "undefined"
('' + null); // → "null"
('' + undefined); // → "undefined"El set soportado:
| Operación | Qué hace | Notas |
|---|---|---|
| s.length | Conteo de caracteres | No conteo de bytes — Unicode-safe |
| s.charAt(n) / s.charCodeAt(n) | Caracter / código en index | 0-indexado |
| s.indexOf(needle) | Posición del primer match, o -1 | NO 0 cuando no se encuentra |
| s.lastIndexOf(needle) | Posición del último match, o -1 | |
| s.slice(start, end) | Substring [start, end) | Indices negativos soportados |
| s.substring(start, end) | Substring [start, end) | Negativos se vuelven 0 |
| s.substr(start, len) | Substring de len chars | Deprecated; funciona en SSJS |
| s.toLowerCase() / s.toUpperCase() | Case fold | Locale-aware en motores más nuevos |
| s.replace(target, repl) | Reemplaza primer match (string) o todos (regex /g) | |
| s.split(sep) | Array de substrings | |
| s.match(regex) / s.search(regex) | Info del match regex / posición | |
| s + s2 | Concatenación | NULL/undefined coerced a "null"/"undefined" |
| Platform.Function.Format(template, args) | Estilo printf con placeholders {0} | Args como array |
| Platform.Function.FormatNumber(n, fmt, loc) | Formateo locale de números | "N2", "C", "P", "F", etc. |
| Platform.Function.FormatDate(d, fmt, loc) | Formateo locale de fechas | Devuelve string |
| String(x) / ('' + x) | Stringificación explícita | |
Referencia:
- Salesforce Developer — Referencia de Platform Functions (Format / FormatNumber / FormatDate) ↗
- MDN — Métodos String.prototype (filtrá a ES5 / pre-2010 para SSJS) ↗
Lo que sobrevive en producción
indexOf devuelve -1 cuando no se encuentra, no 0
Misma trampa que el CHARINDEX de SQL (que devuelve 0), pero invertida: en SSJS String.indexOf devuelve -1 para "no encontrado" y 0 para "encontrado al inicio." La lógica condicional que chequea > 0 va a saltearse silenciosamente matches en posición 0.
// EN RIESGO — saltea matches en posición 0 (ej. "@example.com")
if (email.indexOf("@") > 0) {
// Trata "@example.com" como "no @ encontrado"
}
// CORRECTO — chequea por el centinela real de "no encontrado"
if (email.indexOf("@") > -1) { /* encontrado */ }
if (email.indexOf("@") !== -1) { /* encontrado, equivalente */ }No hay String.prototype.trim confiable — polyfillealo con regex
SpiderMonkey 1.7 no manda .trim() consistentemente. No dependas de él.
// EN RIESGO — puede tirar "trim is not a function" en tenants viejos
var clean = email.trim();
// PORTÁTIL — siempre funciona
var clean = email.replace(/^\s+|\s+$/g, "");
// O envolvé una vez y reusá
function trim(s) {
return s == null ? s : String(s).replace(/^\s+|\s+$/g, "");
}Lo mismo aplica a padStart, padEnd, includes, startsWith, endsWith — ninguno está presente confiablemente. Polyfillealos o sustituí.
+ coerce null y undefined a strings literales
JavaScript stringifica eagerly: "hello " + null es "hello null", no "hello ". Esto se cuela en mensajes de log y contenido de email donde esperabas un string vacío.
// EN RIESGO — el mensaje de log se vuelve "Got null rows" en lugar de "Got 0 rows"
var count = null; // porque LookupRows devolvió nada y te olvidaste de defaultear
Write("Got " + count + " rows");
// → "Got null rows"
// SEGURO — coalesce nulls a un default sensato antes de string-concat
var count = rows ? rows.length : 0;
Write("Got " + count + " rows");
// → "Got 0 rows"
// Helper para escrituras de log
function safeStr(v) {
return (v === null || v === undefined) ? "" : String(v);
}
Write("Email: " + safeStr(emailMaybe));El bug es invisible en dev porque el dato de dev rara vez es null. Surfacea en logs de producción que se leen como disculpas garbleadas.
replace solo reemplaza el primer match salvo que uses regex con /g
Un error común: pasar un string como argumento de búsqueda a replace y esperar que se reemplacen todos los matches.
// EN RIESGO — solo reemplaza la primera coma
"a,b,c,d".replace(",", ";");
// → "a;b,c,d" (no "a;b;c;d" como podrías esperar)
// CORRECTO — regex con flag /g
"a,b,c,d".replace(/,/g, ";");
// → "a;b;c;d"
// O usá split + join para swaps simples de delimitador
"a,b,c,d".split(",").join(";");
// → "a;b;c;d"Para search strings dinámicos, tenés que construir un objeto RegExp:
var needle = ",";
var re = new RegExp(needle, "g");
"a,b,c,d".replace(re, ";");Platform.Function.Format es el reemplazo SSJS para template literals
Los template literals (backticks + ${...}) no existen. Para strings interpolados multi-arg, Platform.Function.Format es más limpio que una cadena de concatenaciones con +.
// VERBOSO — muchas concatenaciones se vuelven difíciles de leer
var msg = "Subscriber " + subKey + " (" + email + ") moved to tier " + tier
+ " at " + Now();
// MÁS LIMPIO
var msg = Platform.Function.Format(
"Subscriber {0} ({1}) moved to tier {2} at {3}",
[subKey, email, tier, Now()]
);El array de args puede contener números, strings, fechas — se coerce a strings durante el format. La sintaxis de placeholder {0}, {1} matchea index del array.
Decisión rápida
Usá Platform.Function.Format cuando:
- Construyendo strings con 2+ valores interpolados.
- El string es un mensaje de log, mensaje de error, o copy user-facing.
Usá concatenación con + cuando:
- 1–2 interpolaciones simples y los operandos están garantizados no-null.
- Adentro de un loop apretado donde cada llamada a función cuenta.
Usá un regex /g con .replace cuando:
- Reemplazás todas las ocurrencias de un substring.
- El patrón de búsqueda es dinámico — construí vía
new RegExp(pattern, "g").
Polyfilleá en lugar de usar métodos de string ES2015+ cuando:
- El script tiene que funcionar entre tenants SFMC más viejos. Asumí siempre que el tenant viejo existe.
Usá Platform.Function.FormatNumber / FormatDate cuando:
- El output va a un usuario (CloudPage, body de email) y el locale importa.
Relacionado
- Basics — superficie de lenguaje soportada
- Platform.Function — el namespace donde Format / FormatNumber / FormatDate viven
- MC SSJS gotchas — ver #1 (sin JS moderno — muchos idioms de string faltantes)
- MC SQL — Funciones de string — hermano para la superficie SQL; muchas de las mismas consideraciones de NULL / index / case-fold aplican
Próximas páginas de referencia SSJS: Date · Encoding · Hashing · categorías de funciones Util · Style Guide.
Más snippets how-to para patrones comunes de producción — DE add/update/upsert, manejo de errores, paginación de callouts, etc.