javascript基础系列:堆栈内存(stack&he
忙了一段时间,很容易忘记更新博客文章,拖延症很严重,今天晚上趁着有时间,继续系统温习,希望对大家有所帮助。本文章仅代表前端岚枫的个人观点,有不正确还望指出。
浏览器运行机制及基本类型与引用类型的区别
/*
* 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)
解析如下图:<br />
image.png
<br />浏览器想要执行代码:
- 从电脑内存中分配一块内存,用来执行代码(栈内存=》stack)
- 分配一个主线程用来自上而下执行js代码
基本类型: 按值操作(直接操作的是值),所以也叫作值类型<br />引用类型:操作的是堆内存的地址(按引用地址操作的)
堆栈内存
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]
解析如下图:<br />
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}}
解析如下图:<br />
image.png
js中数据类型检测
- typeof
tppeof [val]: 用来检测数据类型的运算符<br />基于typeof检测出来的结果
- 首先是一个字符串
- 字符串中包含对应的类型
局限性:
- typeof null => "object", 但是null并不是对象
- 基于typeof无法细分当前值是普通对象还是数组对象,因为只要对象数据类型,返回的结果都是“object”
console.log(typeof typeof typeof [])
//=> typeof [] => "object"
//=> typeof "object" => "string"
//typeof检测的结果都是字符串,所以只要两个及以上同时检测,最后结果必然是"string"
console.log(alert(1)) //undefined
- alert(1): 执行浏览器内置的alert方法,执行方法的时候弹出一个"1"(方法的功能),此方法没有返回值,默认的返回值为undefined
<br />把其它类型转换成数字<br />(1) Number()它是按照浏览器从底层机制,把其它数据类型转换为数字
- 字符串: 看是否包含非有效数字字符,包含结果就是NaN
- 布尔: true => 1 false =>0
- null: 0
- undefined: NaN
- 引用类型值: 都要先转换为字符串再转换为数字
{}/正则/函数等 => NaN<br />[]=> 0<br />['12'] => '12' => 12<br />[12, 23] => '12,23' NaN<br />(2) parseInt/parseFloat([val])遵循按照字符串从左到右查找的机制找有效数字字符(所以传递的值一定是字符串,不是也要转换为字符串然后再查找)<br />parseInt(undefined) => parseInt('undefined') => NaN<br />parseInt('') => NaN 没找到有效字符串
- instanceof
用来检测当前实例是否率属于某个类
- constructor
基于构造函数检测数据类型(也是基于类的方式)
- Object.prototype.toString.call()
Object.prototype.toString.call():检测类型最好的办法
js中的操作语句: 判断、循环
- 条件成立做什么? 不成立做什么
- if/else if/ else
条件多样性;等于、大于、小于的比较/一个值或者取反等,最后都是要计算出是true或者false
if(条件) {
条件成立执行
} else if(条件2){
条件2成立执行
}
...
else {
以上条件都不成立
}
- 三元运算符
三元运算符:简单if/else 的特殊处理方式<br />(1) 如果处理的事情比较多,我们要用括号包起来,每一件用逗号分隔<br />(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<br />(2) default等价于else,以上都不成立的事情<br />(3) 不加break,当前条件成立执行完成后,后面条件不论是否成立都要执行,直到遇到break为止(不加break可 以实现变量在某些值的情况下做相同的是激情)<br />(4) 每一种case情况的比较用的都是===“绝对相等”
let a = 10;
循环
重复做某些事情就是循环
- for循环
(1) 创建循环初始值<br />(2) 设置(验证)循环执行条件<br />(3) 条件成立执行循环体中的内容<br />(4) 当前循环结束执行步长累计操作<br />循环体中的两个关键词:<br />continue:结束当前这轮循环(continue后面的代码不再执行),继续执行下一轮循环<br />break: 强制结束整个循环(break后面代码也不再执行),而且整个循环啥也不干直接结束
for(var i = 0; i< 5; i++) {
console.log(i)
}
- for in 循环
for in 在遍历的时候,优先循环数字属性名(从小到大)
var obj = {
name: 'lanfeng',
age: 23
}
for (var key in obj) {
// 每一次循环key 变量存储的值: 当前对象的属性名
// 获取属性值:obj[属性名]=》 obj[key] obj.key /obj[key]
}
- for of 循环
- while
- 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>
解析:<br />id: 操作元素的id值<br />className: 操作元素的class样式类的值<br />innerHTML: 操作的元素的内容(可以识别标签)<br />innerText: 和innerHTML的区别是不能识别标签<br />tagName:获取元素的标签名(一般大写)<br />style: 操作元素的行内样式,属性值是一个新的对象(CSSStyleDeclaration)<br />
image.png
<br />js中的加减乘除本应该是进行数学运算(如果遇到值不是数字类型也需要基于Number()方法把其转换为数字,再进行运算),但是js中加法有特殊情况:相加过程中遇到字符串直接变为字符串拼接
let i = '10'
i = i + 1 => '10' + 1 => '101'
i+=1 => '101'
i++ => 11
// i++ 和以上两种不完全一样,它是纯粹的数学运算