阅读 33

javascript基础系列:堆栈内存(stack&heap)(二)

忙了一段时间,很容易忘记更新博客文章,拖延症很严重,今天晚上趁着有时间,继续系统温习,希望对大家有所帮助。本文章仅代表前端岚枫的个人观点,有不正确还望指出。

浏览器运行机制及基本类型与引用类型的区别

/*
 * 1. 创建变量a,放到当前栈内存变量存储区域中
 * 2. 创建一个值12,把它存储到当前栈内存值区域中(简单的基本类型值是这样存储的,复杂的引用类型值不是这样的)
 * 3. = 为赋值,其实赋值是让变量和值相互关联的过程
*/
let a = 12; //,
let b = a;
b = 13
console.log(a)

/*
 * 复杂值(引用类型值)的存储,分三个步骤
 * 1. 在内存中分配出一块新内存,用来存储引用类型值(堆内存=> heap)=》 内存有一个16进制地址
 * 2. 把对象中的键值对(属性名:属性值)依次存储到堆内存中
 * 3. 把堆内存地址和变量关联起来
*/

let n = {
	name: '岚枫'
};
let m = n;
m.name = '秋秋'
console.log(n.name)
复制代码

解析如下图:
image.png
浏览器想要执行代码:

  1. 从电脑内存中分配一块内存,用来执行代码(栈内存=》stack)
  2. 分配一个主线程用来自上而下执行js代码

基本类型: 按值操作(直接操作的是值),所以也叫作值类型
引用类型:操作的是堆内存的地址(按引用地址操作的)

堆栈内存

let n = [10, 20]
let m = n;
m[0] = 20;
x = [30, 40]
x[0] = 200;
m = x
m[1] = 200;
n[2] = 400;
console.log(n, m, x)// [20,20, 400] [200, 200] [200, 200]

复制代码

解析如下图:
image.png

let a = {
	n: 1
}
let b = a
a.x = a= {
	n:2
}
console.log(a.x) //undefined
console.log(b) // {n:1,x: {n:2}}


复制代码

解析如下图:
image.png

js中数据类型检测

  1. typeof

tppeof [val]: 用来检测数据类型的运算符
基于typeof检测出来的结果

  • 首先是一个字符串
  • 字符串中包含对应的类型

局限性:

  • typeof null => "object", 但是null并不是对象
  • 基于typeof无法细分当前值是普通对象还是数组对象,因为只要对象数据类型,返回的结果都是“object”

image.png

console.log(typeof typeof typeof [])
//=> typeof [] => "object"
//=> typeof "object" => "string"
//typeof检测的结果都是字符串,所以只要两个及以上同时检测,最后结果必然是"string"

复制代码
console.log(alert(1)) //undefined
复制代码
  • alert(1): 执行浏览器内置的alert方法,执行方法的时候弹出一个"1"(方法的功能),此方法没有返回值,默认的返回值为undefined


把其它类型转换成数字
(1) Number()它是按照浏览器从底层机制,把其它数据类型转换为数字

  • 字符串: 看是否包含非有效数字字符,包含结果就是NaN
  • 布尔: true => 1 false =>0
  • null: 0
  • undefined: NaN
  • 引用类型值: 都要先转换为字符串再转换为数字

{}/正则/函数等 => NaN
[]=> 0
['12'] => '12' => 12
[12, 23] => '12,23' NaN
(2) parseInt/parseFloat([val])遵循按照字符串从左到右查找的机制找有效数字字符(所以传递的值一定是字符串,不是也要转换为字符串然后再查找)
parseInt(undefined) => parseInt('undefined') => NaN
parseInt('') => NaN 没找到有效字符串

  1. instanceof

用来检测当前实例是否率属于某个类

  1. constructor

基于构造函数检测数据类型(也是基于类的方式)

  1. Object.prototype.toString.call()

Object.prototype.toString.call():检测类型最好的办法

js中的操作语句: 判断、循环

  1. 条件成立做什么? 不成立做什么
  • if/else if/ else

条件多样性;等于、大于、小于的比较/一个值或者取反等,最后都是要计算出是true或者false

if(条件) {
	条件成立执行
} else if(条件2){
	条件2成立执行
}
...
else {
	以上条件都不成立
}
复制代码
  • 三元运算符

三元运算符:简单if/else 的特殊处理方式
(1) 如果处理的事情比较多,我们要用括号包起来,每一件用逗号分隔
(2) 如果不需要处理事情,可以使用null/undefined占位

let a = 10
if(a>0 && a< 20) {
	a++; //  => a+=1 a= a+1 => 自身累加1
  console.log(a)
}

//三元运算符表示
a>0 && a< 20 ? (a++, console.log(a)) : null
复制代码
  • switch case

(1) 每一种case情况结束最好都加上break
(2) default等价于else,以上都不成立的事情
(3) 不加break,当前条件成立执行完成后,后面条件不论是否成立都要执行,直到遇到break为止(不加break可 以实现变量在某些值的情况下做相同的是激情)
(4) 每一种case情况的比较用的都是===“绝对相等”

let a = 10;

复制代码

循环

重复做某些事情就是循环

  1. for循环

(1) 创建循环初始值
(2) 设置(验证)循环执行条件
(3) 条件成立执行循环体中的内容
(4) 当前循环结束执行步长累计操作
循环体中的两个关键词:
continue:结束当前这轮循环(continue后面的代码不再执行),继续执行下一轮循环
break: 强制结束整个循环(break后面代码也不再执行),而且整个循环啥也不干直接结束

for(var i = 0; i< 5; i++) {
	console.log(i)
}
复制代码
  1. for in 循环

for in 在遍历的时候,优先循环数字属性名(从小到大)

 var obj = {
 	name: 'lanfeng',
   age: 23
 }
for (var key in obj) {
// 每一次循环key 变量存储的值: 当前对象的属性名
// 获取属性值:obj[属性名]=》 obj[key] obj.key /obj[key]
}
复制代码
  1. for of 循环
  2. while
  3. do while
<div id="app"></div>
<script>
 let  box = document.getElementById('app') 

let AA = box.style
AA.color = 'red'

let BB = box.style.color
BB = 'red'

console.dir(box)
 </script>
复制代码

解析:
id: 操作元素的id值
className: 操作元素的class样式类的值
innerHTML: 操作的元素的内容(可以识别标签)
innerText: 和innerHTML的区别是不能识别标签
tagName:获取元素的标签名(一般大写)
style: 操作元素的行内样式,属性值是一个新的对象(CSSStyleDeclaration)
image.png
js中的加减乘除本应该是进行数学运算(如果遇到值不是数字类型也需要基于Number()方法把其转换为数字,再进行运算),但是js中加法有特殊情况:相加过程中遇到字符串直接变为字符串拼接

let i = '10'
i = i + 1 => '10' + 1 => '101'
i+=1 => '101'
i++ => 11
// i++ 和以上两种不完全一样,它是纯粹的数学运算
复制代码

如想了解更多请扫描二维码,关注公众号

qrcode_for_gh_4d3763fa9780_258 (1).jpg