记录一个JS引用类型的知识点
之前学习引用类型的时候只是大致了解了什么是引用类型,它和基本数据类型的区别,比如一个是保存在栈内存,一个保存在堆内存之类的。后来在做一个栗子时出现错误,一开始没有想到是因为引用类型的关系,记录如下:
栗子出自JavaScript DOM编程艺术里面的第四章案例研究,做一个简易的图片库。主要就是通过点击超链接,将链接所包含的图片在同个窗口显示。思路是用一个占位符(placeholder)用于展示照片,当点击超链接时,获取该超链接的href属性(getAttribute方法),再修改placeholder的src属性(setAttribute方法)。同时需要关注点击超链接后取消浏览器默认行为(默认会在新窗口打开)。
基本HTML代码如下:
// An highlighted block
<!DOCTYPE html>
<html>
<head>
<title>this is my gallery</title>
<meta charset="utf-8"/>
</head>
<body>
<h1>Here are the pictures</h1>
<ul>
<li>
<a href="./素材/国王排名.jpeg" >国王排名</a>
</li>
<li>
<a href="./素材/小丸子.jpeg">小丸子</a>
</li>
<li>
<a href="./素材/秒速五厘米.jpg">秒速五厘米</a>
</li>
</ul>
<img src="./素材/天气之子.jpeg" id="placeholder" style="width: 500px; height: 300px;"/>
</body>
</html>
JS部分如下:
// An highlighted block
<script>
var placeholder = document.getElementById("placeholder");
function showPic(whichPic){
var source = whichPic.getAttribute("href");
placeholder.setAttribute("src", source);
}
var items = document.getElementsByTagName("a");
//方式一
function myOnClick(obj){
obj.onclick = function(event){
event = event || window.event;
event.preventDefault();
showPic(obj);
}
}
for(var i=0; i<items.length; i++){
myOnClick(items[i]);
console.log(typeof items[i]);//结果为object
}
//方式二
for( var i=0; i<items.length; i++){
//var item = items[i];此处为了验证item[i]对象是否存在
items[i].onclick = function(event){
event = event || window.event;
event.preventDefault();
//showPic(items[i]);
console.log(typeof items[i]);//结果为undefined,此处是引用类型
}
}
</script>
方式一可以运行,而方式二会报错,提示无法对undefined对象使用getAttribute方法。一开始以为是因为不能在响应函数内获取绑定该事件的元素,所以items[i]才是undefined,但是如果一开始便将items[i]赋给变量item, 在响应函数内获取item是object类型,所以排除了响应函数的问题。
后来在交流群中问了大佬,大佬回了四个字,引用类型。于是我依稀地记起了,引用类型保存的是地址,又回顾了一下相关知识点。
上述引用自: 菜鸟教程.
也就是说,引用类型操作的其实是指针,用赋值过程来看可能更加清楚:
上述引用自: 菜鸟教程.
所以items[i]实际上是一个地址而非对象,当然不能对其使用getAttribute方法了。
JS里的引用类型包括:object、Array、RegExp、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。
最后,基本数据类型和引用类型的在内存中的情况可以表示如下:
a,b为基本数据类型,b是由a赋值得到,但两者除了初始值相同以外没有其他联系,后续操作互不影响。
obj,obj2为两个对象,obj2由obj赋值得到,他们保存的是同个堆内存地址,故指向同个对象,后续操作会相互影响。