一、变量类型
变量分为值类型和引用类型:typeof可以简单的检测数据类型;
值类型的特点:
- 占用空间固定,保存在栈中;
- 保存与复制都是值本身;
- 使用typeof检测数据的类型;
- 基本数据类型是值类型;
引用类型的特点;
- 占用空间不固定,保存在堆中;
- 保存与复制的是指向对象的一个指针;
- 使用instanceof检测数据的类型;
- 使用new()方法构造出的对象是引用型;
ECMAScript规定变量包含两种不同数据类型的值,基本类型值和引用类型值;在给变量赋值的时候,解析器必须要明确这个值是基本类型还是引用类型值,因为他们的赋值方式是不同的;string/number/boolean/null/undefined都是基本数据类型;因此可以操作保存在变量中是实际值,此时变量储存的是实际的值;而引用类型的值是保存在内存中的,此时变量储存的是内存的地址,而不是真实的值;而我们操作引用类型的变量时,实际操作的是它引用地址对应的对象,而不是直接操作对象的; 基本类型和引用类型的操作原理
var number1= 1, number2=number1; number1=2;//改变了number1的值 console.log(number1);//2 console.log(number2);//1 console.log(number1===number2);//false
基本数据类型,也叫原始数据类型,不可能数据类型;引用数据类型,也叫对象类型和可变类型;
不可变的意思是,这个值是不可以改变的,如果变量修改了字符串,以前的字符串会销毁,然后再次赋值;而可变的意思是可以改变对象的属性值;这只是对数据来说的,javascript本身是可以自由进行数据类型转换的,javascript的变量是无任何类型的,只是一个标识符,变量可以赋值任何类型的值;string的所有方法,都是不会改变原有字符串的,比如toUpperCase返回的值,其实是一个新字符串,原有字符串不变,这就是string方法的原理;
//单纯的属性复制 var s1 = { o:1 }; var s0 = {}; s0.o = s1.o; console.log(s0); // {o:1} s1.o =2; console.log(s0) // {o:1} //对象复制 var s1 = { o:1 }; var s0 = {}; s0 = s1; console.log(s0);//{o:1} s1.o =2; console.log(s0) //{o:2} 关于变量提升: 对象: console.log(a) //undefined Var a = {a:1} 实际执行:var a; console.log(a) a={a:1} 函数: Console.log(a) // function a() { console.log()} 所以可以这样: Const y = a; a() //可以执行 Console.log(a()); // undefined function a() { console.log()} 函数表达式: console.log(h()); // type error h is not function console.log(h()); ////undefined var h = function() { console.log('q') } var h = function() { console.log('q') } console.log(h); // function () { console.log('q') } Console.log(h()); //undefined 同时还出发函数 输出q
变量名的优先级(当有多个名字重复的变量时候)
- 局部变量高于同名全局变量;
- 参数变量高于同名全局变量;
- 局部变量高于同名参数变量;
全部变量和局部变量的特性
- 忽略块级作用域
- 全部变量是全局对象的属性
- 局部变量是调用对象的属性;
- 作用域链;
- 内层函数可访问外层函数局部变量;
- 外层函数不能访问内层函数局部变量;
- 生命周期:
- 全局变量;除非被显示删除,否则一直存在;
- 局部变量:自声明起至函数运行完毕或被显示删除;
- 回收机制:
- 标记清除
- 引用计数;
爱前端 爱设计 爱生活