学习 JavaScript (七) 内存问题
内存问题是 JavaScript 比较底层的东西,依葫芦画瓢学会了怎么使用变量,但是对于内存的概念依然模糊,今天让我们一起来了解一下内存在这门语言是怎么样的存在。
内存在不同类型的数值面前表现有很大的不同。我们把值赋给一个变量,解析器必须确定这个值是什么类型,先来了解变量的两个类型:
基本类型:简单的数据段:Undefined、Null、Boolean、Number、String,按值访问,可以直接操作实际的值。
引用类型:保存在内存中的对象:Object、Array。。JavaScript 赋值保存着对象的某个变量时,操作的是对象的引用;在为对象添加属性的时候,操作的是实际的对象。
复制基本类型的数据时,计算机会重新分配一个位置给新的变量;但是复制引用类型的数据,计算机只是复制了一个指针,指向原有的对象。所以改变其中一个引用类型数据的属性时,访问另一个引用类型数据的属性能得到一样的结果,比如:
复制基本类型并改变其中一个变量:
let a = 20;
let b = a;
b = 30;
console.log(a) // 20

复制引用类型并改变其中一个变量的属性:
let m = {a:10, b:20};
let n = m;
n.a = 15;
console.log(m.a) // 15

m,n 都指向一个引用类型的对象,所以改变 n 的属性会导致 m 的属性改变。上面表示的是变量之间基本的复制,但是注意:** 在所有函数的参数传递中,都是按值传递的,不是按照引用传递的 **。比如:
function setName(obj){
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
let person = new Object();
setName(person);
alert(person.name); // "Nicholas"
JS 内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)。其中「栈」存放基本类型变量,遵循后进先出的原则;「堆」存放引用类型,堆存取数据的方式,则与书架与书非常相似,知道名字就能取出来用;池存放常量。
检测一个变量是不是基本类型,用 typeof 操作符就可以搞定,但是这个操作符在遇到对象或者 null 时,返回 Object,我们不知道具体的类型。这时候,用 instanceof 来确认是什么类型的对象。
内存泄漏与回收
不再用到的内存,没有及时释放,就叫做内存泄露。
大多数语言提供自动内存管理,减轻程序员的负担,这被称为“垃圾回收机制”(garbage collector)。原理很简单:找出那些不再继续使用的变量,然后释放其占用的内存。
JavaScript 具有自动垃圾收集机制,不用程序员操太多心。而不同的浏览器可能会采取不同的回收策略,现代浏览器最常用的方式是标记清除,其次是引用计数。
- 标记清除。垃圾收集器会给内存中的所有变量都添加标记,然后清除一些还会被使用的标记,即凡是环境中还会用到的变量,被其他变量引用的变量。还有标记的变量就会被垃圾收集器删除,完成内存的清除工作。
- 引用计数。原理也很简单,跟踪每个变量被引用的次数。这里会产生一个棘手的问题,就是遇到 “循环引用” 就没招了。解决的方法是不再使用的对象,我们把它设置成空对象 Null 。看下面的例子:
function(){
let a = new Object();
let b = new Object();
a.oneObject = b;
b.anotherObject = a;
}
上面的代码中,a 和 b 通过各自的属性实现相互引用,两者的被引用次数都是 2 。如果采用标记清楚策略,由于函数执行结束,这两个对象都离开了作用域,都会被清除。但是,采用引用计数策略,a 和 b 都还继续存在,因为他们的引用次数永远不会是 0。此时,只有手动断开引用。
function(){
let a = new Object();
let b = new Object();
a.oneObject = b;
b.anotherObject = a;
// 消除循环:
a.oneObject = null
b.anotherObject = null;
}
学习 JavaScript (七) 内存问题的更多相关文章
- 前端学习 第七弹: Javascript实现图片的延迟加载
前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img src="" x-src="/acsascas ...
- JavaScript学习系列之内存模型篇
一个热爱技术的菜鸟...用点滴的积累铸就明日的达人 正文 如果真的想学好一门语言,那么一定要了解它内存模型,本篇文章就带你走进JavaScript的内存模型,由于本人才疏学浅,若有什么表述有误的地方, ...
- 一步步学习javascript基础篇(8):细说事件
终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...
- 学习javascript数据结构(二)——链表
前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...
- 学习javascript数据结构(一)——栈和队列
前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...
- 《如何正确学习JavaScript》读后小结
在segmentfault上读的一篇学习JavaScript路线的文章,做个小结. 一.简介.数据类型.表达式和操作符 (1)<JavaScript权威指南>前言1-2章&< ...
- C语言学习 第七次作业总结
C语言学习 第七次作业总结 数组可以分为数组和多下标数组(在传统的国内C语言书本中,将其称为二/多维数组). 数组名称 在之前的课程中,大家应该都有印象,对于int a这样的定义,会为变量 a 声明一 ...
- 一步步学习javascript基础篇(6):函数表达式之【闭包】
回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; } //函数声明语法定义 2. var sum = funct ...
- 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)
前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
随机推荐
- 浅谈编程语言中的新宠Python,你叫它如何不火?
论述 凡是对编程有所关注的朋友都已经知道,Python公布于1991年,即使出现的时间不是很遥远,但是在众多爱好者的贡献下已经发展到全民Python的地步. Python最近火起来的笼统原因:面向企业 ...
- .NET之JSON序列化运用
1.项目引用NuGet包:搜索:Newtonsoft.Json 2.序列号实例 using System; using System.Collections.Generic; using System ...
- 配置teredo,启用ipv6,xx-net
最近使用XX-NET科学上网 ,提示要配置使用IPv6.根据github的上win10配置ipv6方式(https://github.com/XX-net/XX-Net/wiki/IPv6-Win10 ...
- S3C6410板子移植 Android2.2
一:Android简介 1.什么是Android: Android是一种基于linux的自由及开放源代码的操作系统,主要适用于移动设备,如智能手机和平板电脑,是由google公司和开放手机联盟领导和开 ...
- PHP之cookies小练习
//5-1.php 1 <? error_reporting(E_ALL ^ E_NOTICE); if ($_COOKIE['username']!="") { echo ...
- MATCH_PARENT和FILL_PARENT之间的区别?
很多人表示对于很多工程中的MATCH_PARENT出现在layout中感到不明白,过去只有FILL_PARENT和WRAP_CONTENT那么 match_parent到底是什么类型呢? 其实从And ...
- Linux用户登录日志查询
# 1 utmp.wtmp.btmp文件 Linux用户登录信息放在三个文件中: 1 /var/run/utmp:记录当前正在登录系统的用户信息,默认由who和w记录当前登录用户的信息,uptime记 ...
- SQL*Loader FAQ
SQL*Loader FAQ: Contents [hide] 1 What is SQL*Loader and what is it used for? 2 How does one use th ...
- salesforce lightning零基础学习(四) 事件(component events)简单介绍
lightning component基于事件驱动模型来处理用户界面的交互.这种事件驱动模型和js的事件驱动模型也很相似,可以简单的理解成四部分: 1.事件源:产生事件的地方,可以是页面中的输入框,按 ...
- web优化(一)
今天读完了<高性能网站建设进阶指南>,记得博客园的某位前辈说,关于前端方面的书,带指南两个字的一般都是比较牛逼的,上一本看到的好书是<javascript权威指南>是淘宝前段团 ...