let name = "啊啊啊"
let str = `you are name ${name}`
console.log(str)
name = "呃呃呃"
console.log(str)
you are name 啊啊啊
you are name 啊啊啊 // 还是输出 啊啊啊 怎么解决?
回答
字符串是不可变的
需要对属性进行劫持,可以使用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 + '');
str在赋值的时候就已经确定了,所以有两个办法:
获取的时候再去计算。我的方案和YoLinDeng 都是这种
被修改了之后,重新赋值一次。vue 的方案,监听变量,改变之后再重新生成一下