<button id="btn">btn</button>
function log () {
console.log('111')
}
let btn = document.querySelector('#btn')
btn.addEventListener('click', log)
btn.addEventListener('click', function () {
console.log(log)
log = null
console.log(log)
})
第一次点击输出:
111
log函数
null
后续点击输出:
111
null
null
问题?
为什么log函数赋值为null后,后续点击还会执行?
这个其实就是个值传递和引用传递的问题,前面两个哥们说得很有意思,但是我觉得都没说到点子上。
JS 中基本数据类型
基本的数据类型有:
undefined,boolean,number,string,null
。 基本类型存放在栈区,访问是按值访问的,就是说你可以操作保存在变量中的实际的值。也就是说,这种赋值类似于拷贝了一份。a和b在
var b = a;
后就再也没有关系了。互不影响。引用赋值
引用类型指的是对象:js中的
array
和object
。可以拥有属性和方法,并且我们可以修改其属性和方法。引用对象存放的方式是:在栈中存放变量名(该变量的值是堆中真实数据的指针(对象在堆中的存放地址)),在堆中存放数据(真正的数据)。对象使用的是引用赋值。当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在堆中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
JS 函数是值传递
JS是值传递,那么传递引用类型和基础类型都是值传递,都是拷贝一份,但是引用类型变量实际上存的是对象/数组的指针,所以对于引用类型的传递,函数调用时候产生的实参是相当于变量的指针拷贝。另外对于函数来说,定义函数的时候,函数名实际存放的是具体函数的一个指针,参考上面关于堆栈存储的说明。
用你这个例子来说明:
所以你看,产生上面的结果就很容易理解了吧?