变量类型
- 基本数据类型:Underfined、null、Boolean、Number、String
- 引用类型:由多个值构成的对象,是保存在内存中的对象。
动态属性
引用类型可以动态添加属性和方法,赋值;
基本类型不可以(虽然不会报错);
var person = new Object();
person.name = '小米';
alert(person.name) //'小米'
var name = '小明';
name.age = 27;
alert(name.age) //undefined
复制变量值
基本类型:会在变量对象上创建一个新变量,然后复制值给新变量,等于复制出来了。
引用类型:也会在变量对象上创建一个新的变量,然后将储存的值复制给新变量,但是不同的是这个值是一个指针(地址值),指向堆中的对象。所以2个变量引用的是同样一个对象(好比你影分身多少个,你家的房子也不会多出来一个),修改其中一个的值,另一个也会受影响
var num1 = 1;
var num2 =num1 ;
num1++ //2
console.log(num2) //1
//引用类型
var obj1 = new Object();
var obj2 = obj1;
obj1.name = '小米';
console.log(obj2.name) //小米
传递参数
所有函数的参数都是按值传递,如同把外部的参数复制一遍,基本类型不会影响外部的参数,但是引用类型会影响。(这部分本人也不太能得很透彻)
//基本类型
var num1 = 10
function setNum(num){
num = 20;
}
setNum();
console.log(num1); //10
//下面传入对象的例子,很容易给人认为参数是按引用传入的,因为修改obj的内容也会影响到外卖的Object
//但是第三个例子就能证明不是按引用地址传入
function setObjet(obj){
obj.name = '小米';
obj.age = 13;
}
var object = new Object();
setObjet(object)
console.log(object); //{name:'小米';age:13}
//如果按照引用传递的话,那么Object打印出来的值应该是name:大米;
function setObjet(obj){
obj.name = '小米';
obj.age = 13;
obj = new Object();
obj.name = '大米'
console.log(obj); //{name:'大米'}
}
var object = new Object();
setObjet(object)
console.log(object); //{name:'小米';age:13}
执行环境以及作用域
执行环境:定义了变量或者函数与有权访问的其他数据。
全局执行环境:最外围的执行环境;
函数都有自己的执行环境,当执行一个函数时,函数的环境会被推入环境栈中,而执行后,就将其弹出,把控制权返回给之前的执行环境
变量对象:保存了环境中定义的所有变量与函数。(web浏览器中全局的执行环境变量被认为是window对象)
作用域链:当代码在环境执行时,会创建一个作用域链,作用域的前端始终包含着当前执行代码所在环境的变量对象。如果是函数的话,最开始只包含arguments对象。作用域链中的下个变量对象,来自包含本作用域的外部环境,一直这样延续到全局执行环境为止。
标识符的解析,是沿着作用域一级一级的从前往后搜索,直到找到为止,找不到就报错。
var red = 'red';
function setcolor1(params) {
var blue ='blue'
console.log(1,red); //1,red
getColor2()
console.log(1,gray) //报错
function getColor2(params) {
var gray;
gray ='gray';
console.log(2,gray) //gray
console.log(2,blue) //bule
console.log(2,red); //red
}
}
setcolor1()
console.log(red); //red 如果setcolor()里没报错的话 就会输出
console.log(blue); //blue
console.log(gray); //gray
总的来说就是外面不能访问里面的变量,里面可以访问外面的变量。
延长作用域链
目前的理解是通过将要延长的变量或者函数通过return作为返回值传递出来。
块级作用域
书上是说没有块级作用域,在if跟for循环中定义的变量(没声明或者var)在花括号外面仍然可以获取使用,但是如果声明变量为let外部将访问不到。
声明变量
使用var声明变量会自动添加到最近的环境变量中,在函数中最近的环境变量就是函数的局部环境。如果没有使用var声明的话,改变量会自动添加到全局环境。
查询标识符
当某环境中为了读取或者写入而引用一个变量时,必须通过搜索来确定标识符实际代表什么。
搜索的过程从作用域链的前端开始,然后向上逐级查询与给定名字匹配的标识符。如果局部环境中找到了该标识符,搜索过程则停止。
垃圾收集
js具有自动垃圾收集机制:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器按照固定周期执行这一操作。通常是通过对变量进行标记来清除。比如函数的局部变量在执行完函数后,就没有存在的必要。因此系统会自动清除他们,释放内存。