You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS自定义Templater类嵌套方法正常但链式调用报错问题求助

问题原因

当前所有元素生成方法(div/span/p等)直接返回HTML字符串,字符串原型上不存在你定义的元素方法,链式调用时会抛出方法未定义错误。

改造方案

需要做3处核心调整:

  • 给Templater类新增内部缓存属性,存储累计生成的HTML字符串
  • 所有元素方法生成标签片段后追加到缓存,返回当前类实例this支持链式调用
  • 自定义toString方法返回缓存的完整HTML字符串,可按需配置调用后是否清空缓存以支持实例复用

改造后完整代码

class Templater {
    // 私有属性存储HTML缓存
    #htmlBuffer = '';

    transform(tags) {
        // 兼容嵌套的Templater实例,自动转成字符串
        return tags.map(item => item instanceof Templater ? item.toString() : item).join("");
    }
    // 返回值结构:[属性字符串,  inner内容数组]
    attributesCheck(tags) {
        let attributeObject = {};
        tags.forEach((item) => {
            if(typeof item === 'object' && item !== null && !Array.isArray(item) && !(item instanceof Templater)) {
                attributeObject = item; 
            }
         })
         const content = tags.filter(item => (typeof item !== 'object' || item instanceof Templater))
        let objectArr = Object.entries(attributeObject);
        let classIndex; 
        let idIndex;
        objectArr.forEach((item, index) => {
            if(item[0] === 'class') {
                classIndex = index; 
            }
            if (item[0] === 'id') {
                idIndex = index; 
            }
        })
        const classItem = objectArr[classIndex]; 
        const idItem = objectArr[idIndex]; 
        objectArr = objectArr.filter(item => item[0] !== 'class' && item[0] !== 'id')
        if (idItem) {
            objectArr.unshift(idItem); 
        }
        if (classItem) {
            objectArr.unshift(classItem); 
        }
       
        let attrString = ''; 
        objectArr.forEach(item => {
            attrString += ` ${item[0]}="${item[1]}"`
        })

        return [attrString, content]; 
    }

    // 抽离单个标签生成逻辑,返回字符串,兼容嵌套场景
    #createTag(tagName, ...tags) {
        const [attrString, content] = this.attributesCheck(tags);
        if(tagName === 'br') {
            if(tags.length) throw new Error('Nested content is not allowed');
            return `<br>`;
        }
        return `<${tagName}${attrString}>${this.transform(content)}</${tagName}>`;
    }

    div(...tags) {
        this.#htmlBuffer += this.#createTag('div', ...tags);
        return this;
    }
    span(...tags) {
        this.#htmlBuffer += this.#createTag('span', ...tags);
        return this;
    }
    br() {
        this.#htmlBuffer += this.#createTag('br');
        return this;
    }
    p(...tags) {
        this.#htmlBuffer += this.#createTag('p', ...tags);
        return this;
    }

    // 自定义toString,返回结果后默认清空缓存,不需要清空可删除第二行
    toString() {
        const result = this.#htmlBuffer;
        this.#htmlBuffer = '';
        return result;
    }
}

测试用例验证

const template = new Templater(); 
// 单个标签场景
console.log(template.div('1454', {id: 'fixing'}).toString());
// 输出:<div id="fixing">1454</div>
console.log(template.div('World of Templates', {id: "card", class: 'first'}).toString());
// 输出:<div class="first" id="card">World of Templates</div>

// 嵌套场景
console.log(template.div(
    template.p('Hello', {id: 'fix', class: "first-p"}),
    template.p('World')
).toString());
// 输出:<div><p class="first-p" id="fix">Hello</p><p>World</p></div>

// 链式调用场景
console.log(template.span('Hello').span('World').toString());
// 输出:<span>Hello</span><span>World</span>

内容的提问来源于stack exchange,提问作者Rurohi53

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:24:00