JS内存、变量与数据

内存

  • 内存:内存条通电后产生可存储数据的空间(临时的)
  • 分为:栈内存(存储变量)和堆内存(存储对象)
    每块内存都有两个数据:内部存储的值和自身的地址

变量

变量:由变量名和变量值构成,在内存中占有一定的空间。在编程语言中,其实变量就是一个名字,用来储存和代表不同值的东西。

声明变量

1.var a=1
2.let b=2
3.const c=3 创建的值(可以理解为常量)不能修改并且必须在定义时初始化(赋值)

4.funtion fun()声明函数也相当于声明变量
5.class Person{}创建类也相当于声明变量
6.import fun from'./index.js'模块导入也相当于声明变量
7.Symbol创建唯一的值 let a=Symbol(100) let b=Symbol(100) console.log(a==b)//false

变量的作用域

变量的作用域就是定义这个变量的区域。在函数内部声明的为局部变量,只能在函数内部访问;全局变量拥有全局作用域,在当前文档任何代码位置都可以访问。
ES6中新增了代码块,在代码块中声明的变量将成为代码块所在函数的局部变量

if (true) {
		var a=1
	}
	console.log(a)//1

if (true) {
		let a=1
	}
	console.log(a)//Uncaught ReferenceError: a is not defined
  • 变量提升:简单来说就是可以先使用变量稍后在声明而不会发生异常,这是因为将声明变量的语句提升到函数或者语句的最前面,提升后的变量默认值为undefined
var声明的变量会进行变量提升
console.log(a) //undefined
	var a=1
在 ECMAScript 6 中,let(const)将不会提升变量到代码块的顶部。因为在变量被声明之前引用会抛出引用错误,这个变量从代码块一开始就处于“暂时性死区”直到变量被声明、
console.log(a) //t.html:11 Uncaught ReferenceError: Cannot access 'a' before initialization
	let a=1

数据

存储在内存中代表特定的一些信息,本质上就是一串二进制数字。
特点:可传递,可计算。

数据类型:

  • 基本数据类型:
    • string :所有单引号 双引号 反引号包起来的东西
    • number :常规数字和NaN(not a number)注意NaN和任何值包括自己都不相等!所以不能通相等来判断是否为有效数字
            console.log(('aa') == NaN);//false

            console.log(10 == NaN); //false

            console.log(NaN == NaN);//false
        isNaN:用来判断一个数是否为有效数字。true:不是有效数字 false:是有效数字。
               在检测时会首先判断是否为number类型,如果不是将调用number()转换后,number类型再判断是否为NaN类型,如果是number类型则直接判断是否为NaN类型。
        console.log(isNaN('aa'));//true 不是有效数字
        console.log(isNaN(10));//false 是有效数字

  
  + boolean :true false
  + null(空对象指针)
     - 初始化时赋值为null,代表是个空值
     - 结束时赋值为null,让其变为垃圾对象,等待回收
    let person={name:'jack'}
    person=null//让person的指针指向null,空引用
  + underfined(未定义)
  • 引用数据类型:
    • object :任何一个对象都是由一个或者多个键值对组成的
    • array
    • function
null与underfined的区别:都代表没有
* null:声明并赋值,值为null(一般是手动设置为null,后期知道准确值再赋予);
例:
    let num=null//let num=0;一般最好赋值为null,因为0不是空值,在栈内存中占有内存空间
    num=13

* underfined:声明但是未赋值
例:
    let num
    console.log(num)//underfined

数据类型的转换

1、转换为string类型:

1)String()
    `String(123)`

2)[val].toString()
    console.log([].toString());//'' 当你尝试输出一个对象或一个变量时 JavaScript 会自动调用变量的 toString() 方法
    console.log(({name: 'jack'}).toString());//[object Object] 因为Object.prototype.toString()不是用来转换为字符串的,而是用于检测数据类型
    console.log(null.toString());//Uncaught TypeError null与underfined禁止直接toString(),但是是可以转换为'null' 'underfined'的
    

3)加法运算
    其余的情况调用toString()方法一般都是在外面包裹上''
    加法运算:任何类型与string类型进行相加,都会转换为string类型然后拼接,没有string类型则转换为number类型进行运算
    let a=123
    let b='hello'
    console.log(a+b)//123hello

2、转换为number类型:

  • 1、Number():遵循V8引擎的底层机制

    • 1)如果是Boolean值,true和false将分别转换为1和0。
    • 2)如果是数字值,只是简单的传入和返回。
    • 3)如果是null值,返回0。
      console.log(Number(null));//0
    • 4)如果是undefined,返回NaN。
      console.log(Number(undefined));//NaN
    • 5)如果是字符串:
      • ① 字符串中只包含数字时,转换为number类型
        console.log(Number('123'));//number
      • ② 字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样也会忽略前导零);
        console.log(Number('123.1'));//123.1
      • ③ 如果字符串是空的(不包含任何字符),则将其转换为0;
        console.log('')//0
      • ④ 如果字符串包含任意一个非有效字符,就将其他转换成NaN.
        console.log(Number('123.1.1'));//NaN
        `console.log(isNaN(Number('50px')));//true 字符串中有一个为非有效数字就会被转换为NaN
      • ⑤ 将引用数据类型转换为number,是基于tostring()方法将其转换为string类型后再转换为number,只要字符串中有非有效数字就为NaN
        console.log(Number({}));//NaN
        console.log(Number([]));//0 []---''---0
        console.log(Number([12]));//12 [12]→'12'→12
        console.log(Number([11, 23]));//[11,23]→'11,23→'NaN
  • 2、parseInt():先转换为字符串然后从左向右查找

    • 1)如果第一个非空格字符不是有效数字,parseInt()就会返回NaN; 用parseInt()转换空字符串会返回NaN、
      console.log(parseInt(''))//NaN 没找到有效数字就是NaN
      console.log(parseInt('s1'))//NaN

    • 2)如果第一个非空格字符为有效数字,继续向下转换,直到遇到非数字字符,将其之前的转换
      console.log(parseInt('50px'));//50
      console.log(parseInt('50.5'));//50

      1. 如果字符串以"0x"开头且后跟数字字符,就会将其当作一个十六进制整数;
      1. 如果字符串以"0"开头且后跟数字字符,就会将其当作一个八进制整数;
  • 3、parseFloat():
    和parseInt类似,从第一个非空字符开始,直到遇到一个无效的浮点字符结束,所以字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。
    console.log(parseFloat('50.5.5'));//50.5

    • Number与parseInt的区别:
      • Number:根据V8引擎的底层机制,不同的类型应该怎么转换
      • parseInt:根据额外提供的机制,如果是字符串则根据如上的规则,不是字符串先将其转换为字符串然后按照规则进行转换
            console.log(Number('50.5px'));//NaN

            console.log(parseInt('50.5px'));//50

            console.log(parseFloat('50.5px'));//50.5
  • 4、四则运算符
    • 规则:
      • 加法运算:有string类型时全部转换为string进行拼接;没有string类型转换为number类型进行加法运算
      • 其他运算:全部转换为number类型然后进行运算,NaN和任何类型运算结果都是NaN类型
        let a='hello'
        let b=123
        console.log(a-b)//NaN

        综合运算:
        console.log(10+null+true+[]+underfined+''中国'+null+[]+10+false)//11underfined中国null10false
          ① 10+null=10
          ②10+true=11
          ③11+[]=11+''='11'
          ④'11'+underfined='11underfined'...

3、转换为boolean类型:

  • 转换规则:以下六种情况转为false,其余转换为true
    1)0
    2) ""
    3)underfined
    4) null
    5)NaN
    6)'false'

  • 转换方式:

    • 1)Boolean()
    • 2)!/!!:取反,先转换为boolean类型,然后取反
      console.log(!1)//false console.log(!!1)//true
    • 3)判断语句
        if(''){
            console.log('true')
        }else{
            console.log('false'    )
        }
    

数据类型的检测

  • 1、typeof [val]:用于检测数据类型的运算符
    • 1)结果是一个字符串
    • 2)字符串中包含对应的数据类型
    • 3)能检测的数据类型:string number boolean object function undefined
    • 4)局限性:
① null用typeof检测结果为object
console.log(typeof null)//object
② 不能区分具体的对象类型,全部为object
console.log(typeof [1,2])//object
练习:注意运算顺序从右向左
console.log(typeof typeof typeof [])//string
  • 2、instanceof :用于检测当前实例是否属于某个类
  • 3、constructor:基于构造函数检测数据类型
  • 4、Object.prototype.toString.call():检测数据类型最佳方式

本节要点
1、
number():遵循c++底层原理:
字符串中有一个无效字符就位NaN
'' null转换为0
undedined转换为NaN
true为1 false为0
引用类型先调用toString()再转换为number类型:{}为NaN []为0 [12]为12 [12,34]为NaN
parseInt() parseFloat():先调用toString方法再从左向右侧查找是否有有效数字
isNaN():返回值为boolean类型,先转换为number类型,再判断是否为NaN
typeof():外面包裹上"",输出为字符串形式,能识别string number boolean undefined object(null 识别为object,不能区分具体的object类型)
2、
console:页面中是什么输出什么
alert prompt confirm输出字符串形式

数据传递---堆栈底层机制

基本数据类型

        let a=12
        let b=a
        b=13
        console.log(a);//12           

引用数据类型

    let n={
            name:'jack'
        }
        let m=n
        m.name='rose'
        console.log(n.name);//rose

练习

  • 1、
        let n=[10,20]
        let m=n
        let x=m
        m[0]=100
        x=[30,40]
        x[0]=200
        m=x
        m[1]=300
        m[2]=400
        console.log(n, m, x);
 //[100, 20] [200, 300, 400] [200, 300, 400]
  • 2、
    var a='abc'+123+456;//'abc123456'
	var b='456'-'123'//333
	var c=100+true+21.2+null+undefined+'Tencent'+[]+null+9+false//'NaNTencentnull9false'
  • 3、
重点:连等号a=b=1实际上执行顺序是 a=1 b=1
    let a={
            n:1
        }
        let b=a
        a.x=a={
            n:2
        }
        console.log(a.x);//underfined
        console.log(b);//{n:1;{x:2}}
  • 4、如下会有什么问题?
let a={name:'tony'}
let b=a
a.x=b  //对象中的属性值是对象本身,对象本身又有这个属性,无限循环会导致内存溢出
  • 5、深入理解
<div id="box"></div>
注意:只要堆内存中的值被修改,浏览器就会基于DOM映射机制把页面中的元素重新渲染

let box=document.getElementById('box')
box.style.backgroundColor='red' //背景颜色设置为红色

let aa=document.getElementById('box').style
aa.backgroundColor='yellow'//背景颜色为黄色
如下图表示:
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- ``` let bb=document.getElementById('box').style.backgroundColor bb='green' //背景颜色为无色 ``` 如下图表示:
posted @ 2019-11-21 22:26  我就是要学习  阅读(231)  评论(0编辑  收藏  举报