Logan

Results 45 issues of Logan

# 对象的底层数据结构 > JavaScript中的对象是基于**哈希表**结构的。 ## 哈希表(Hash table)、哈希函数(Hash Function)与哈希碰撞(Hash Collision) **哈希表** 又称*散列表*,根据键直接访问在内存存储位置的数据结构。通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。 **哈希函数** 又称*散列函数*、*散列算法*,上述映射函数即为哈希函数,是一个表示键和内存存储值位置的映射关系的函数。常见的构造哈希函数的方法有*直接定址法*、*除留余数法*、*随机数*法等。 **哈希碰撞** 又称*哈希冲突*,指不同键经过哈希函数计算后得到相同哈希地址的情况。具有相同函数值的关键字对该哈希函数来说称做*同义词*。 ## 处理哈希碰撞 **开放定址法** 当关键字`key`的哈希地址`p=H(key)`出现冲突时,以`p`为基础,产生另一个哈希地址`p1`...,直到找出不冲突的哈希地址`pi`,将相应元素存入其中。 > 优点:储空间更加紧凑,利用率高。\ > 缺点:冲突元素间产生关联,无法直接删除,会破坏寻址链,只能在删除节点上作删除标记。 ![开放定址法处理哈希碰撞](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Hash_table_5_0_1_1_1_1_0_SP.svg/380px-Hash_table_5_0_1_1_1_1_0_SP.svg.png) **拉链法** 又称*链地址法*,将散列到同一个存储位置的所有元素保存在一个链表中。 > 优点:处理冲突简单,非同义词决不会发生冲突,因此平均查找长度较短。\ > 缺点:指针需要额外的空间,降低构建哈希表时的效率。...

前端知识体系-JavaScript基础

# JavaScript 数据类型 ## 7种原始类型(Primitive data type) > 原始类型的值本身都是不可变的(immutable) ### 布尔类型 `true` / `false`。 ### Null类型 `null`,特指对象的值未设置,是一个字面量,不是全局属性。 ### Undefined类型 `undefined`,是全局属性,不是保留字,可使用`void`操作符代替。 ### 数字类型 基于IEEE754标准的双精度64位二进制格式的值。 - 展开查看数字类型特殊常量 - 检查值是否大于或小于`+-Infinity`,可使用常量`Number.MAX_VALUE`和`Number.MIN_VALUE`。 - 双精度浮点数的取值范围是`Number.MIN_SAFE_INTEGER`和`Number.MAX_SAFE_INTEGER`。 ###...

前端知识体系-JavaScript基础

对**词法环境**和**执行上下文**不太了解的朋友,建议先阅读系列文章的前两篇,有助于理解本文,链接 -> [深入ECMAScript系列目录地址(持续更新中...)](https://github.com/logan70/Blog) # 一、词法作用域 首先我们来看一个例子(来自冴羽大大的博客[JavaScript深入之词法作用域和动态作用域](https://github.com/mqyqingfeng/Blog/issues/3)): ```js var scope = 'global scope' function checkscope(){ var scope = 'local scope' function f(){ return scope } return f() } checkscope() ``` ```js...

深入JavaScript系列

说到JavaScript的原型和原型链,相关文章已有不少,但是大都晦涩难懂。本文将换一个角度出发,先理解原型和原型链是什么,有什么作用,再去分析那些令人头疼的关系。 # 一、引用类型皆为对象 原型和原型链都是来源于对象而服务于对象的概念,所以我们要先明确一点: **JavaScript中一切引用类型都是对象,对象就是属性的集合。** `Array类型`、`Function类型`、`Object类型`、`Date类型`、`RegExp类型`等都是引用类型。 也就是说 **数组是对象、函数是对象、正则是对象、对象还是对象。** ![](https://user-gold-cdn.xitu.io/2018/11/9/166f6326edc99c76?w=435&h=184&f=png&s=17467) # 二、原型和原型链是什么 上面我们说到对象就是属性(property)的集合,有人可能要问不是还有方法吗?其实方法也是一种属性,因为它也是`键值对`的表现形式,具体见下图。 ![](https://user-gold-cdn.xitu.io/2018/11/9/166f64bf36e55099?w=347&h=182&f=png&s=30826) 可以看到`obj`上确实多了一个`sayHello`的属性,值为一个函数,但是问题来了,`obj`上面并没有`hasOwnProperty`这个方法,为什么我们可以调用呢?这就引出了 **原型**。 每一个对象从被创建开始就和另一个对象关联,从另一个对象上继承其属性,这个`另一个对象`就是 **原型**。 当访问一个对象的属性时,先在对象的本身找,找不到就去对象的原型上找,如果还是找不到,就去对象的原型(原型也是对象,也有它自己的原型)的原型上找,如此继续,直到找到为止,或者查找到最顶层的原型对象中也没有找到,就结束查找,返回`undefined`。 **这条由对象及其原型组成的链就叫做原型链。** 现在我们已经初步理解了原型和原型链,到现在大家明白为什么数组都可以使用`push`、`slice`等方法,函数可以使用`call`、`bind`等方法了吧,因为在它们的原型链上找到了对应的方法。 OK,**总结一下**: 1. **原型存在的意义就是组成原型链**:引用类型皆对象,每个对象都有原型,原型也是对象,也有它自己的原型,一层一层,组成原型链。 2. **原型链存在的意义就是继承**:访问对象属性时,在对象本身找不到,就在原型链上一层一层找。说白了就是一个对象可以访问其他对象的属性。 3. **继承存在的意义就是属性共享**:好处有二:一是代码重用,字面意思;二是可扩展,不同对象可能继承相同的属性,也可以定义只属于自己的属性。 # 三、创建对象 对象的创建方式主要有两种,一种是`new`操作符后跟函数调用,另一种是字面量表示法。...

深入JavaScript系列

# 一、内存是什么 我们现在常用的计算机都属于 **冯·诺依曼体系计算机**, 计算机硬件由 **控制器、运算器、存储器、输入设备、输出设备** 五大部分组成。 我们通常所说的内存就是 **存储器**。 > 常用的内存都是易失性存储器(需要通过不断加电刷新来保持数据,一旦断电就会导致数据丢失),所以需要一种容量大、低成本的非易失性存储器来进行数据的存储,这就是外存,例如磁带、软盘、硬盘、光盘、闪存卡、U盘等。可以将外存理解为输入输出设备,因为外存是需要通过I/O接口进行数据存取的,而内存是由CPU直接寻址的。外存中的程序需要通过I/O接口调入内存中才可以运行。 内存就是程序运行的地方,其实程序本质上就是指令和数据的集合。所以说内存是指令和数据的临时存储器,然后CPU对内存中的指令和数据进行处理。 # 二、内存的使用 不管什么程序语言,其运行都依赖内存,内存生命周期基本是一致的: 1. 分配所需要的内存 2. 使用分配到的内存(读、写) 3. 不需要时将其释放\归还 在JavaScript中,第一步和第三步由js引擎完成的,对于编程人员是隐藏的。但是这并不意味着我们不需要了解JavaScript中的内存机制,了解内存机制有助于我们写出更优雅、性能更好的代码。 # 三、JavaScript的内存模型 JavaScript数据类型有基本类型和引用类型两大类,基本类型有Undefined、Null、Boolean、Number、String、Symbol六中,引用类型有Object,所有的JavaScript变量值将会是七种的其中之一。这些数据类型在内存中是怎样存储的?我们来看一下JavaScript的内存模型。 > 说是`JavaScript的内存模型`其实不太准确,只是便于理解。由于JavaScript中的内存分配是由js引擎完成的,所以更准确的描述是`js引擎的内存模型`。 一个运行中的程序总是与内存中的一部分空间相对应。这部分空间叫做 Resident Set...

深入JavaScript系列