js 变量、作用域和内存问题

时间:2022-03-14 06:09:15

基本类型和引用类型

  • 5种基本类型:undefined、null、boolean、number、string

  • 引用类型:由多个值构成的对象

属性

引用类型可以动态添加属性,而基本类型不可以

var p = new Obj();
p.name = "huyuping";
console.log(p.name)//huyuping

var a;
a.name = "huyuping";
console.log(a,name)//出错

复制变量值

  • 基本类型

会在变量的对象上创建了一个新值,然后把复制到新变量分配的位置上。

下面的我形象化的帮助大家理解

这就相当于a和b都有一个房子,a把值复制给b后,b的房子了也有了这个值。

  • 引用类型

当从一个变量向另一个变量复制引用类型的值时,同时也会将存储在变量类型中的复制一份放到为新变量分配的内存空间中。

这可以这样理解:a,b都有自己的地方,a的值时放在另一个屋子里的,a复制给b,那a和b都要在哪个房子里去拿值,这个房子就是给a分配的内存,b的内存也指向哪个位置。

传递参数

  • 基本类型
    在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数)。
unction addTen(num) {
num+=10;
return num;
}
var count = 20;
var result = addTen(count);
console.log(count);//20
console.log(result);//30

这里函数有个局部变量num,在使用之后就被回收了,然后函数返回一个值。

我们看下面一种情况

function addTen(num) {
num+=10;
return num;
}
var count = 20;
addTen(count);
console.log(count);//20
console.log(addTen(count));//30

这次,我们没有定义result变量,而是直接输出addTen(count),输出的值还是30,这更说明了num时局部变量,不会影响count的值。

  • 引用类型
    在向参数传递引用类型的值时,会把这个值在内存中的地址复制给局部变量,因此这个局部变量的变化会反映在函数外部。
function setName(obj) {
obj.name = "huyuping";
}
var person = new Object();
setName(person);
console.log(person.name);//huyuping

在这个函数内部,obj和person引用的时同一个对象,所以为obj添加name属性的时候,在外面也有反应。

作用域

  1. script:全局变量、全局函数
  2. 函数:自上而下、由里到外

e.g.1

alert(a);//undefined
var a = 1;
function fn1 () {
alert(a);//undefined

var a = 3;
}
fn1();
alert(a);//1

分析:

1.预解析:

1)a= undefined

2)fn1 = function fn1 () {alert(a);var a = 3; }(函数里的a是新定义的,所以预解析的时候会先是var a = undefined)

2.表达式:

1)a=1;
2)调用函数
1.预解析 a= undefined
2.表达式 a=3

e.g.2

        alert(a);//undefined
var a = 1;
function fn1 () {
alert(a);//1
a = 3;
}
fn1();
alert(a);//2

分析:

1.预解析:

1)a= undefined
2)fn1 = function fn1 () {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;
2)调用函数
1.预解析 (没有预解析,此时返回父级作用域(从子级作用域返回到父级作用域的过程叫作用域链)) 找到a=1,改为a=2

e.g.3

 alert(a);//undefined
var a = 1;
function fn1 (a) {
alert(a);//undefined
a = 3;
}
fn1();
alert(a);//1

分析:

1.预解析:

1)a= undefined
2)fn1 = function fn1 (a) {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;
2)调用函数
1.预解析
function fn1 (a) a相当与var a
a=undefined
2.逐行解读代码
a=3

e.g.4




var a = 1;
function fn1 (a) {
alert(a);//1
a = 3;
}
fn1(a);
alert(a);//1

分析:

1.预解析:

1)a= undefined
2)fn1 = function fn1 (a) {alert(a);var a = 3; }

2.逐行解读代码:

1)a=1;
2)调用函数
1.预解析 function fn1 (a) a相当与var a
因为fn1(a),相当于对a传了参数,所以function fn1 (a)相当于function fn1 (var a = 1)
2.逐行解读代码
a=3

if、for 是通透的不是作用域
注意:火狐解析不到if语句里面包着的函数体,所以尽量不要向if、for里面定义变量或函数