1 写在前面
以下内容大纲
- JS运行机制
- 栈内存
- 堆内存
- 思考题
- 判断语句 & 三元运算符 & switch
- 相等 & 绝对相等
2.1.5 JS运行机制
问题:
var a = 12; var b =a; b = 13; console.log(a); =>12 var obj1 ={n:100}; var obj2 =obj1; obj2.n = 200; console.log(obj1.n); =>200
浅分析JS的运行机制
- 当浏览器(内核/引擎)渲染和解析JS时,会提供一个供JS代码运行的环境,我们把这个环境称之为“全局作用域”(global/window scope)
- 代码自上而下执行(之前还有一个变量提升阶段)
栈内存
本身就是一个提供JS代码执行的环境
所有的基本类型值都会直接点再栈内存中开辟一个位置进行存储
基本数据类型的值会存储在当前作用域之下
- var a = 12;
首先开辟一个空间存储12
再当前作用域中声明一个变量a (var a)
让声明的变量和存储的12进行关联(把存储的12赋值给a, 赋值操作叫定义)
基本数据类型(也叫做值类型),是按照值来操作的:把原有的值复制一份放到新的空间或者位置上,和原来的值没有关系
堆内存
用来存储引用类型中的信息值
对象存储的是键值对
函数存储的是代码字符串
引用数据类型的值不能直接存储在当前作用域之下(因为存储内容过于复杂),我们需要先开辟一个新的空间(理解为仓库)把内容存储在这个空间
var obj1 = {n:100};
- 首先开辟一个新的内存空间,把对象的键值对一次存储起来(为了保证后面可以找到空间,此空间有一个16进制地址)
- 声明一个变量
- 让变量和空间地址关联一起(把空间地址赋值给变量)
引用类型不是按值操作,它操作空间地址:把原来的空间地址赋值给新的变量,但原来的空间没有被克隆,还是一个空间,这样就会出现多个变量关联的是相同的空间,相互之间就会存在影响
思考题1
/* *1.形成一个全局作用域(栈内存) 2.代码自上而下执行 1)首先开辟一个新的堆内存(AAAFFF111),吧键值对存到堆内存 n:10 m:obj.n*10 =>obj.n此时堆内存信息还没有存储完成,空间地址没有给obj,此时obj是undefined,此时obj.n<=>undefined.n */ var obj = { n:10, m:obj.n*10 =>//Cannot read property 'n' of undefined }; console.log(obj.m);
总结:注意,是先有值,后有对象
思考题2
var ary1 = [3,4]; var ary2 = ary1; ary2[0] = 1; // =>ary1 = [1,4] ary2 = [4,5]; ary2[1] = 2; //=>ary2=[4,2] ary1[1] = 0; //=>ary1 = [1,0] console.log(ary1,ary2);
2.1.6 JS中的判断语句
1、if / else if / else
var num = 12; if(num>10){ num++; }else if(num>0 && num<10){ num--; }else{ num+=2; } console.log(num); if(0){ //在JS中只有"0/NaN/空字符串/null/undefined"这五个值转换为布尔类型为false } if('3px'+3){ //在JS中,+ - * /都是数***算,除 + 意外,其余运算符都在运算的时候,如果遇到了非数字类型的值,首先会转换为数字类型(Number),然后在进行运算 // + 在JS中除了数学相加,还有字符串拼接作用(如果运算中遇到字符串,则拼接,否则数学相加) // > <都是数学比较,非数字比较都是先转换(Number)为数字 }
问题1
var num = parseInt('width:35.5px'); //=>num = NaN if(num==35.5){ alert(0); }else if(num==35){ alert(1); }else if(num==NaN){ alert(2); }else if(typeof num=='number'){ //先算typeof num //在比较 alert(3); //alert输出的都是字符串的'3‘ }else{ alert(4); }
typeof (逻辑运算符?)
用来检测数据类型方式之一,除此之外还有:
- instanceof (逻辑运算符)
- constructor (方法)
- Object.prototype.toString.call() (方法)
//语法 //typeof [value] typeof 12 =>number //返回值:使用typeof检测出来的结果是字符串,字符串包含着对应的数据类型,例如:"string"/"number"/"object"/"boolean"/"undefined"/"function" typeof null => "object" 因为null代表空对象指针(没有指向任何内存空间 typeof 检测数组/正则/对象最后都返回的是"object",也就是基于这种方式无法细分对象 console.log(typeof []); =>"object" console.log(typeof typeof []) =>"string"
2.1.7 三元运算符 & switch
语法:条件?成立事件:不成立事件;
var num = 12; if (num>10){ num++; }else{ num--; } //=>三元运算符 num>10?num++:num--;
//特殊 1、如果三元运算符某一部分不需要任何处理,用null/undefined/void 0...占位即可 num>10?num++:null; num>10?num++:void 0; num>10?num++:undefined; 2、如果需要执行多项任务,用小括号包起来 num=10; bum>10?(num++,num*10):null;
Switch
- 加break,不加会顺序后延,且后面条件全部执行
- default等价于else
- 每一次case的比较都是===“绝对相等”
let a = 10; switch(a){ case 1: console.log('hh'); break; case 2: console.log('hh'); break; default: console.log('hh'); } //在a=1/2事都执行console.log('hh'); //不加break可以实现变量在某些值之下做相同的事情 switch(a){ case 1: case 2: console.log('hh'); break; default: console.log('hh'); }
思考题:
let a = '1'; switch(a){ case 1: console.log('hh'); break; case 2: console.log('xx'); break; default: console.log('dd'); //=>输出'dd' 每一次case的比较都是===“绝对相等” } if(a == 1){ console.log('hh'); //=>输出'hh' }else{ console.log('dd'); }
== VS ===
==:相等(如果左右两边数据类型不同,是默认转换为相同的类型,然后比较)
'5'==5 =>true
===:绝对相等(类型不一样肯定不相等,不会转换为相同数据类型)
'5'===5 =>false