1.伪数组 2.不声明变量直接赋值使用 3.函数执行过程 4.js(栈内存/堆内存)5.作用域

伪数组

  1. 伪数组的特点
    伪数组拥有数组的属性,
    -具有 length 属性 但length属性不是动态的,不会随着成员的变化而变化
    -按索引方式储存数据
    -不具有数组的push(), forEach()等方法
    伪数组本质是一个 Object,而真实的数组是一个 Array
    伪数组的原型 Object.prototype 通过改变原型指向可以将伪数组转为真数组

  2. 常见伪数组

    1. 函数内部的 arguments,扩展操作符可以将 arguments 展开成独立的参数
    2. DOM 对象列表 如 通过 document.getElementByTags 获取的 dom元素
    3. JQuery对象 如 $(‘div’)
  3. 伪数组转为真数组

遍历添加入一个空数组

var arr = [];
for(var i = 0; i < arrLike.length; i++){
   arr.push(arrLike[i]);
}

利用数组的slice()方法

;[].slice.call(arrLike);
//slice() 方法以新的数组对象,返回数组中被选中的元素。
//或者
Array.prototype.slice.apply(arrLike);
	模拟 slice() 内部实现
Array.prtotype.slice = function(start, end){
        var result = new Array();
        var start = start | 0;
        var end = end | this.length;for(var i = start; i < end; i++){
            result.push(this[i]);
        }
        return result;
    }

变量的声明

JavaScript可以不声明变量直接调用
例如

a = 1;
var b = 1;

两者效果看起来相同,是创建一个变量并赋值为1。但是没有使用var声明的变量会被视为全局变量,而使用var声明的变量会被束缚于函数体内
不声明变量易造成程序错误,也不利于程序的可读性,所以建议声明变量后再进行使用。
所有的变量声明,都是用 var,且语句以 ;结束
不过JavaScript编译器会自动添加;,所以当你忘记加;的时候,程序仍可以运行,不过有可能改变程序的语义,且可读性变低,此处不推荐这样做。

变量的命名

  • 变量必须以字母开头
  • 变量也能以 $ 和 _ 符号开头(不推荐这么做)
  • 变量名称对大小写敏感(y 和 Y 是不同的变量)
  • 变量名称不能包含空格

函数的执行过程(牢记)

内存的存储过程
+ 当你定义一个变量(变量和函数)的时候
+ 会在内存中开辟一段区域来存储内容
+ 浏览器把存储部分分成了两个区域
1. 栈内存
2. 堆内存
+ 在存储的过程中
=> 基本数据类型, 直接把值保存在栈内存里面
=> 复杂数据类型
-> 数据存储在堆里面
-> 把地址存储在栈内的变量里面

**函数的两个阶段(熟读并背诵全文)**⭐⭐⭐⭐⭐

  函数定义阶段
        1. 在堆内存中开辟一段空间
        2. 把函数体内的代码一模一样的当做一个字符串存储在空间中(不执行代码, 不解析变量)
        3. 把空间地址赋值给栈内存中的变量名
函数调用阶段
       
     1.  按照变量名存储的地址找到一个对应的堆内存中的空间
           1.1. 判断变量名是否存在, 如果不存在: xxx is not defined
           1.2. 按照变量名存储的地址查找, 如果不是一个函数存储空间: xxx is not a function

     2. 在 调用栈 中开辟一段新的代码执行空间
     3. 在开辟的代码执行空间中进行 形参赋值
     4. 在开辟的代码执行空间中进行 预解析
     5. 把存储空间内的代码一模一样的复制一份放在执行空间内执行一遍
    	(此时才开始解析变量)
     6. 当代码执行完毕以后, 该执行空间销毁

栈内存和堆内存的区别

JS的内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)。
其中栈存放变量,堆存放复杂对象,池存放常量,所以也叫常量池。
栈数据结构
栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。
栈被称为是一种后入先出(LIFO,last-in-first-out)的数据结构。由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问
为了得到栈底的元素,必须先拿掉上面的元素。

堆数据结构
堆是一种经过排序的树形数据结构,每个结点都有一个值。
通常我们所说的堆的数据结构,是指二叉堆。
堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。
由于堆的这个特性,常用来实现优先队列,堆的存取是随意的

这就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,
但是我们想取任意一本时不必像栈一样,先取出前面所有的书, 
我们只需要关心书的名字。

PS: 需要注意的是闭包中的基本数据类型变量不保存在栈内存中,而是保存在堆内存中。

基本数据类型
Sting、Number、Boolean、null、undefined、Symbol

基本数据类型保存在栈内存中,因为基本数据类型占用空间小、大小固定,通过按值来访问,属于被频繁使用的数据。

引用数据类型
Array,Function,Object…可以认为除了上文提到的基本数据类型以外,所有类型都是引用数据类型。
引用数据类型存储在堆内存中,因为引用数据类型占据空间大、大小不固定。
如果存储在栈中,将会影响程序运行的性能; 引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。 当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体

在这里插入图片描述

let m = { a: 10, b: 20 };
let n = m;
n.a = 15;
console.log(m.a)//m.a=15

👆↑
m、n都是引用类型,栈内存中存放地址指向堆内存中的对象, 引用类型的复制会为新的变量自动分配一个新的值保存在变量中, 但只是引用类型的一个地址指针而已,实际指向的是同一个对象, 所以修改 n.a 的值后,相应的 m.a 也就发生了改变。
在这里插入图片描述
栈内存和堆内存的优缺点
在JS中,基本数据类型变量大小固定,并且操作简单容易,所以把它们放入栈中存储。
引用类型变量大小不固定,所以把它们分配给堆中,让他们申请空间的时候自己确定大小,这样把它们分开存储能够使得程序运行起来占用的内存最小。
栈内存由于它的特点,所以它的系统效率较高。
堆内存需要分配空间和地址,还要把地址存到栈中,所以效率低于栈。

栈内存和堆内存的垃圾回收
栈内存中变量一般在它的当前执行环境结束就会被销毁被垃圾回收制回收, 而堆内存中的变量则不会,
因为不确定其他的地方是不是还有一些对它的引用。
堆内存中的变量只有在所有对它的引用都结束的时候才会被回收。

闭包与堆内存
闭包中的变量并不保存中栈内存中,而是保存在堆内存中。
这也就解释了函数调用之后之后为什么闭包还能引用到函数内的变量。

作用域

一个变量(变量和函数)的生效范围

作用域的分类
    1. 全局作用域
      => 一个 html 页面打开, 就是一个全局作用域
      => window
    2. 私有作用域(函数作用域)
      => 概念: 只有函数生成私有作用域

  提供了三个机制
    1. 变量定义机制
      => 定义在哪一个作用域下的变量就是哪一个作用域的私有变量
      => 只能在该作用域以及后代作用域使用
    2. 变量访问机制
      => 当你需要访问某一个变量的值的时候
      => 首先在自己作用域内查找, 如果有直接使用, 停止查找
      => 如果没有, 去到父级作用域查找, 如果有直接使用, 停止查找
      => 如果还没有, 在去到父级作用域查找
      => 以此类推, 直到全局作用域(window) 都没有, 报错: xxx is not defined
    3. 变量赋值机制
      => 当你需要给一个变量赋值的时候
      => 首先在自己作用域内查找, 如果有直接赋值, 停止查找
      => 如果没有, 去到父级作用域查找, 如果有直接赋值, 停止查找
      => 如果还没有, 就在去到父级作用域查找
      => 以此类推, 直到全局作用域(window) 都没有
      => 把该变量定义为 全局变量 在进行赋值

分清变量的三种情况
    1. 变量定义
      => 必须要有定义变量的关键字
        -> var / function
      => 函数的形参
    2. 变量访问
      => 当你需要用到某一个变量的值
    3. 变量赋值
      => 当你需要给一个变量进行赋值操作
      => 特点: 有赋值符号 或者 实参和形参的交互
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值