JS的换行字符串``, 占位符怎么动态替换

let name = "啊啊啊"
let str = `you are name ${name}`
console.log(str)
name = "呃呃呃"
console.log(str)


you are name 啊啊啊
you are name 啊啊啊 // 还是输出 啊啊啊 怎么解决?

阅读 6.3k
6 个回答

字符串是不可变的

需要对属性进行劫持,可以使用Object.defineProperty或者Proxy
不过需要将name定义到一个对象中:

let obj = {
    name: '啊啊啊'
}

使用Object.defineProperty进行数据监听,在getter中可监听到读取,setter中监听更改。

Object.defineProperty(obj, name, {
    enumerable: true,  //该属性才会出现在对象的枚举属性中
    configurable: true, // 该属性的描述符够被改变,同时该属性能从对应的对象上被删除。
    get(){
        console.log('name属性被读取了')
      },
     set(newVal){
       console.log('name属性被修改了')
       let reg = /{{s*([^s{}]+)s*}}/g  // 正则匹配
        if (reg.test(str)) {
           str = str.replace(reg, newVal)
        }
      }
})

也可使用Proxy,在set中执行相同的事情

const p = new Proxy(obj, {
    get(target, prop) {
        return Reflect.get(...arguments)
    },
    set(target, prop, newValue) {
        let reg = /{{s*([^s{}]+)s*}}/g  // 正则匹配
        if (reg.test(str)) {
           str = str.replace(reg, newValue.name)
        }
        return Reflect.set(...arguments)
    }
})
let name = "啊啊啊"
const func = str => `you are name ${str}`
console.log(func(name))
name = "呃呃呃"
console.log(func(name))

you are name 啊啊啊
you are name 呃呃呃 

str是函数才行

let name = "啊啊啊"
let str = () => `you are name ${name}`
console.log(str())
name = "呃呃呃"
console.log(str())

也能用toString来实现,原理上是一样的

let name = '啊啊啊';
let str = {toString: () => `you are name ${name}`};
console.log(str + '');
name = '呃呃呃';
console.log(str + '');

image.png

str在赋值的时候就已经确定了,所以有两个办法:

  1. 获取的时候再去计算。我的方案和YoLinDeng 都是这种
  2. 被修改了之后,重新赋值一次。vue 的方案,监听变量,改变之后再重新生成一下
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题