JavaScript 引用类型

ES6 遍历数组和对象(本身需要定义迭代器)的值 var v of arr

1.数组


关联数组:数组下标可以自定义,{}。length属性:无。for key in arr遍历。

JavaScript的对象本质就是一个关联数组。 需要用关联数组的地方用对象替代。 伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。

function log()
{ 
    //为了使用unshift数组方法,将argument转化为真正的数组 
var args = Array.prototype.slice.call(arguments); 
args.unshift('(app)'); 
console.log.apply(console, args);
 };

2.对象


内置对象 Object 遍历对象:for in var key in obj 判断属性是否存在于指定对象中:(k in obj) 会检查原型链 ,obj.hasOwnProperty(k)不会检查原型链。

数组最好采用for通过下标遍历

3.函数


Function对象的属性arguments是类数组对象(object like array),有length属性,可以通过数字下标访问属性值。 函数重名的话,后面定义的函数会覆盖前面的。 JavaScript没有函数重载这个概念,但是可以根据不同参数模拟重载,从而复用逻辑。

因为Object的原型链上存在Function.prototype(Object.__proto__===Function.prototype),所以Objectinstanceof Function返回true,同时Function.prototype.__proto__指向Object的prototype属性,自然返回的也是true。并且这也可以理解为什么Object.prototypeinstanceof Object返回为false了。

图片来源:https://blog.csdn.net/lxpblsc/article/details/9032687

一切对象都有一个根源。它是Object.prototype。 根源之上再没有其他根源。Object.getPrototypeOf(Object.prototype)是null。js中除字面量以外的一切引用对象都来自这个“根源”对象。 表达式Object.getPrototypeOf(Function) === Function.prototype的结果是真。这是Function特有的。实际上Function的prototype是一个内置函数,一切函数都派生自这个内置函数,这个内置函数是一个函数工厂。这个内置函数对象的prototype指向“根源”对象。 表达式Object.prototype === Object.getPrototypeOf(Function.prototype)的结果是真。说明了Object跟Function二者之间的联系,是通过“根源”对象联系起来的。

图片引用自:https://blog.csdn.net/jackwen110200/article/details/51850144?utm_source=blogxgwz1 Function.prototype指向”内置函数“。而Object.prototype指向”根源对象“。 因而new Function会产生一个匿名函数,而new Object产生一个plain object。

图片来源:https://www.jianshu.com/p/00dc4ad9b83f

4.JSON


错误: SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse 原因:JSON.parse的参数(从接口查询后,后台返回的数据)已经是对象了,不能再解析成JSON对象了,需要先JSON.stringify,再JSON.parse。 对象浅拷贝:JSON.parse(JSON.stringify(obj))

全局(global)对象

引用类型拷贝

参考链接:https://juejin.im/entry/58217da92f301e005c2de257

垃圾回收

浏览器垃圾回收机制通常就这两个。

(1)引用计数法 不常见。IE9 开始不使用引用计数法了,IE9之后的JavaScript对象都是原生js对象,之前的话部分对象不是原生js对象,比如DOM和BOM,浏览器实现BOM、DOM是由C++的COM(组件对象模型)实现的,而COM就是采用引用计数法。

一个变量存储了一个引用类型,该值的引用次数加一,如果该变量被赋值为另一个变量,则之前的引用类型的引用次数减一。 例如:

var a = {name:"xiaoming"}//{name:"xiaoming"}的引用次数加一
a = {}或者 a = 1;//{name:"xiaoming"}的引用次数减一

当引用类型的引用次数为0时可以被回收。

引用计数法存在的问题:循环引用

比如:

var obj1.a = obj2;
var obj2.b = obj1;

两个对象互相包含对方的引用,这样会导致两个对象都无法被回收。 (2)标记清除法 目前主流浏览器都是采用标记清除法(或者类似的机制)作为垃圾回收机制的,比如safafi、chrome、Firefox、IE、opera,只不过垃圾回收的时间间隔不同。

先给所有在内存中的对象打上标记(至于如何打上标记不是重点,重点是采取什么样的策略),当js执行流进入变量所在环境,比如函数function中,就会清除当前环境中变量的标记,因为环境中的变量无法再访问这些变量了,执行完成后,垃圾回收器会销毁依然存在标记的变量,回收它们所占的内存空间。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券