functioncreateIncrementFixed(i) { let value = 0; functionincrement() { value += i; console.log(value); returnfunctionlogValue() { const message = `Current value is ${value}`; console.log(message); }; }
接着执行到第 10 行,声明了message变量,并将基础数据类型 value的值赋给message,此时value为 1,所以message = "Current value is 1",然后返回logValue函数,increment函数执行完毕,并赋值给log变量。因为闭包对象Closure(createIncrement)的产生,log变量将会引用着increment函数第一次执行时创建的作用域。如图所示,作用域里的 Local 对象「活动对象」中的message = "Current value is 1"。
解释第 25 行,执行logValue函数,寻找message变量。 先查找 Local 活动对象,没找到,发现作用域链中的闭包对象Closure(increment)中存在message,且值为Current value is 1,打印message,logValue函数执行完毕。
1 2
Local 活动对象:仅仅只有处于栈顶的执行上下文,才会生成 Local 对象。 除了 Local 活动对象,作用域链中的其他几种变量对象(Closure/Module/Global)都能够在函数解析时确定
虽然Closure(createIncrement)中的value已经变成了 3,但是并不影响基础数据类型 message 变量中的 value 值。 那是不是只要将引用类型赋值给 message 变量,就可以解决闭包陷阱问题?
onUnload: function () { const { timerId } = this; if (timerId) { // 清除定时器 clearInterval(timerId);
// 将定时器ID设置为null this.timerId = null; } }, });
wx.request 封装
为什么执行reject()之后,还要执行 resolve()?
看到这里时,我有点疑惑,为什么执行reject()之后,还要执行 resolve()? 执行reject()之后,Promise 状态已经被固定了,再执行resolve()也没有意义。打了个断点(**f11 **step into next function call )看下,发现resolve(res)并没有执行。
在进行交易时,A 给 B 转账,需要付款人的签名和收款人的地址(公钥的哈希)。收款方需要知道付款方的公钥(为了验证签名是否有效。实际上其他节点都需要知道付款方的公钥,验证交易合法性)。
这里存在一个问题: :::info 假设 B 的同伙 B’,B’ 伪造一笔 A 到 B 的转账交易,用自己的公钥说是 A 的公钥,然后用假造的私钥签个名,别的节点收到这笔交易后,要假造的公钥去验证这个签名。验证结果肯定是对的,这让别的节点以为这个交易是合法的,这就出问题了。相当于把 A 账上的钱偷走了。 :::
解决这个问题的关键,就是第二种哈希指针。虽然 B’伪造了 A 到 B 的交易,但是实际中 A 转账的时候提供的公钥需要和铸币交易中的公钥对的上,如果对不上,说明该交易不合法。
比特币区块信息
区块信息可以分为两部分:block header 和 block body block header 由以下信息:
version(版本协议)
hash of previous block header(指向前一个区块指针)
merkle root hash(默克尔树根哈希值)
target(挖矿难度目标阈值)
nonce(随机数)
hash of previous block header 只计算区块头部部分的哈希(merkle root hash 保证了 block body 内容不被篡改,所以只需要计算 block header 即可保证整个区块内容不会被篡改)。 区块链中,轻节点(只存储区块 block header 信息)只利用区块链,并不参与区块链系统的维护和构造。