web-dev-qa-db-fra.com

Concaténation de chaînes avec des instructions `if` en JavaScript

J'essaie de configurer un script pour concaténer certaines variables dans une chaîne si elles existent , afin de placer les balises de métadonnées appropriées dans un document HTML restitué.

Mon code de concaténation est:

data = "<html>\n<head>\n" + "</head>\n<body>\n\n" + paras.join("\n\n") + "\n\n</body>\n</html>";

J'essaie d'y ajouter des instructions if telles que les suivantes (entre le premier et le deuxième élément):

    if (typeof metadata_title !== "undefined") {
        "<title>" + metadata_title + "</title>\n"
    }
    if (typeof metadata_author !== "undefined") {
        "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n"
    }
    if (typeof metadata_date !== "undefined") {
        "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n"
    }

Mais je ne peux ajouter aucune de ces instructions directement dans le code de concaténation (une erreur est générée: Unexpected token ().

Quelle serait la meilleure solution pour ajouter de telles déclarations dans ma chaîne de concaténation?

23
木川 炎星

J'utiliserais un opérateur ternaire :

data = "<html>\n"
     + "<head>\n" 
     + ( typeof metadata_title  !== "undefined" ?  "<title>" + metadata_title + "</title>\n"                             : "" )
     + ( typeof metadata_author !== "undefined" ?  "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n" : "" )
     + ( typeof metadata_date   !== "undefined" ?  "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n"     : "" )
     + "</head>\n"
     + "<body>\n"
     + "\n"
     + paras.join("\n\n")
     + "\n"
     + "\n"
     + "</body>\n"
     + "</html>"
;
43
bluish

Je pourrais faire quelque chose d'un peu différent (un peu plus apparenté à la modélisation), principalement parce que je déteste le HTML concaténé fait avec Javascript:

var metadata_title = "Hello";
var metadata_author = "Me";
var metadata_date = "2011-09-07";

var template = "<html>\
            <head>\
                <title>#title#</title>\
                <meta name=\"author\" content=\"#author#\"></meta>\
                <meta name=\"date\" content=\"#date#\"></meta>\
            </head>\
            <body>\
            </body>\
            </html>";

var data = template.replace("#title#", metadata_title != undefined ? metadata_title : "")
                   .replace("#author#", metadata_author != undefined ? metadata_author : "")
                   .replace("#date#", metadata_date != undefined ? metadata_date : "");

Bien sûr, il y a très petite quantité de frais généraux supplémentaires, mais pour moi, c'est moyen plus lisible.

5
Demian Brecht
data = "<html>\n<head>\n" 
    + (
        typeof metadata_title !== "undefined" ?
        "<title>" + metadata_title + "</title>\n" :
        ""
    )
    + (
        typeof metadata_author !== "undefined" ?
        "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n" :
        ""
    )
    + (
        typeof metadata_date !== "undefined" ?
         "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n" :
        ""
    )
    + "</head>\n<body>\n\n" 
    + paras.join("\n\n") 
    + "\n\n</body>\n</html>";
5
scessor

Construisez le document entier dans un tableau, puis joignez-y un "\n" à la fin. (La raison en est bien sûr de ne pas avoir beaucoup de nouvelles lignes éparpillées! Et si vous êtes sur IE7 ou moins, Array#join est considérablement plus rapide qu'une concaténation de chaînes répétée.)

Code ici: http://jsfiddle.net/ZCbCZ/

UPDATEJ'ai oublié d'inclure les "paras" dans le premier violon. Le code avec les paras est ici: http://jsfiddle.net/U8325/1/

Pour ceux qui ne souhaitent pas cliquer et l'essayer, voici le script:

// Not going to define metadata_author just to be saved by typeof :-)
var metadata_title = "Hello";
var metadata_date = "2011-09-07";

// Okay 3 paras for fun
var paras = ["<p>paragraph1</p>", "<p>paragraph2</p>", "<p>paragraph3</p>"];

data = ["<html>", "<head>"]

if (typeof metadata_title !== "undefined") {
    data.Push("<title>" + metadata_title + "</title>");
}
if (typeof metadata_author !== "undefined") {
    data.Push("<meta name=\"author\" content=\"" + metadata_author + "\"></meta>");
}
if (typeof metadata_date !== "undefined") {
    data.Push("<meta name=\"date\" content=\"" + metadata_date + "\"></meta>");
}

data.Push("</head>");
data.Push("<body>");
paras.forEach(function (p) {data.Push(p);});   // Requires ES5; use a for-loop if you don't have it
data.Push("</body>");
data.Push("<html>");
data = data.join("\n");
alert(data);
1
Ray Toal

J'ai aimé la lisibilité de Demian Brecht answer, mais je ne changerais la chaîne que pour un regex , car la fonction replace () ne remplace que la première correspondance (voir plus ici: JavaScript .replace remplace seulement le premier Match )

var metadata_title = "Hello";
var metadata_author = "Me";
var metadata_date = "2011-09-07";

var template = "<html>\
            <head>\
                <title>#title#</title>\
                <meta name=\"author\" content=\"#author#\"></meta>\
                <meta name=\"date\" content=\"#date#\"></meta>\
            </head>\
            <body>\
            </body>\
            </html>";

var data = template.replace(/#title#/g, metadata_title != undefined ? metadata_title : "")
                   .replace(/#author#/g, metadata_author != undefined ? metadata_author : "")
                   .replace(/#date#/g, metadata_date != undefined ? metadata_date : "");
1