在这里想总结比较一下直接赋值和函数式赋值的一些特点和用途
- 直接赋值是及时的,二次调用可能不变
- 函数式赋值延迟性的,二次调用会刷新值,获得最新的
一、简单类型数据赋值比较
- 假设有一个数据 100 传给 a、b
- 这里通过直接赋值和函数式赋值两种方式传递
data = 100
let a = data
let b = function(){return data}
// data 更新为 101
data = 101
console.log(`a:${a},b:${b()}`)
// a:100,b:101
可以得到结论
- 简单类型的数据的赋值是“完完整整”的复制
- 第二种方式是复制函数,它的复制的是函数的地址,指向同一个内容
二、换成对象试试?
data2 = {n:100}
let c = data2
let d = ()=>{return data2}
data2.n = 101
console.log("c:",c,",d:",d())
// c:{n:101},d:{n:101}
- 对象和函数一样,赋值是复制的地址,指向同一个内容
三、函数式赋值的“刷新”
假设 a 被赋值给了一个数值和函数(不要问为什么同时能被赋值一个数值和函数),它就有这样一个特性
- 数值更新了,a 的数值不会更新
- 函数更新了,a 的函数会更新
我想让它们都更新,怎么办?把数值和函数包起来变成一个函数
- a ()=>{ ←(数值 + 函数)}
我无法自己写出一个这样的例子,但我在 React 中见到过这样的情况
let App = React.createElement('div', {className: test}, n)
这里的 n 就是赋值给了实例,想要实时“刷新”,就把它改造成函数
let App = ()={React.createElement('div', {className: test}, n)}
四、setTimeout 函数
- 看一看循环语句和 setTimeout 函数的配合
let i = 1
for (i=1;i<=6;i++){
setTimeout(()=>console.log(i),0)
}
// 打印出 6 个 7
7 7 7 7 7 7 7
这是怎么回事?怎么不打印出 1 2 3 4 5 6?
setTimeout 函数意思是立即执行,i 等于 1 ~ 6 的时候,发生 6 次立即打印 i 但没有执行,当循环结束,i 的值等于 7 的时候,前面的立即打印 i 开始执行,取得 i 的值为 7,于是打印出 6 个 7。
- console.log(i) 只在函数调用的时候执行
- i = 7 后,前面提前准备好的 6 个 console.log(i) 获得 i 的值并开始执行
- 这就是函数赋值延迟性
如果想预期打印出 1 2 3 4 5 6,可以再设置一个变量存起来
let i = 1
for (i=1;i<=6;i++){
let j = i
setTimeout(()=>console.log(j),1000)
}
「@浪里淘沙的小法师」