JavaScript入门篇总结(一)

一,全局变量和局部变量
 
全局变量:全局变量是整个代码中都可以调用的变量。
局部变量:只能在本变量声明的函数内部调用。
 
声明方式全局变量三种方式:
1,使用关键字var声明 
 var a;
2,直接声明
 a;
或者
function test(){
 a //函数内部去掉关键字var 声明的变量是全局的
}
3,定义在window对象上面
window.a;
 解释:
var a ===  a === window.a。其实这三种声明全局变量的方式都是定义在window对象上的,由于window这个对象就是最上层的对象,可以忽略不写(默认是最上层的);
 
二,变量、函数声明
 
在JavaScript中,定义的所有变量、函数都会在自动提取到作用域头部进行声明。
实例:
console.log(a); //undefined
var a = 1;
console.log(a);//1
fun1();//弹出框 函数一
function fun1(){ alert('函数一') };
 
解释:
      上面的代码,在执行的时候,会先把变量a和函数fun1声明提升到作用域头部(这里是最上层作用域window。也可以在函数里面定义这些变量,默认会把定义的局部变量、函数声明提升到函数头部),代码等同下面。
var a;
function fun1(){ alert('函数一') };
console.log(a);//undefined;
a = 1;
fun1();//弹出框 函数一
 
三,变量的生命周期
 
1,全局变量的生命周期,由于全局变量是定义到window对象上的变量,而window对象在页面窗口加载后,就一直存储在内存中,直到页面窗口被销毁,才会被内存释放掉。所以全局变量的生命周期最长,直至整个程序完全被终止,才会被销毁。
2,局部变量的生命周期,局部变量在函数执行完毕后,不存在外部对此局部变量的调用,内存就会立即释放掉这个局部变量,局部变量被销毁。
实例1:
function test(){
     var a = 'aaa';
}
test();
在执行完函数test后,局部变量a就会被内存立即释放掉。
实例2:
function test(){
     var a = 'aaa';
     return function()
       {
            return a + 'bbb';
       } 
}
var b = test();
var c = b();
console.log(c);//'aaabbb'
解释:
1,var b = test()这段代码是执行函数test并将返回值赋值给变量b,所以b是一个函数;
2,由于执行完函数test,外部变量b还存在对局部变量var a = 'aaa'( return a + 'bbb')的调用,所以局部变量a不会被内存释放掉;
3,var c = b() 执行函数b,并将返回值赋值给变量c。执行完函数b由于此时不在存在对局部变量a的调用,所以a被内存释放掉,a被销毁;
4,其实闭包原理就是根据外部还存在对局部变量的调用,所以内存不会立即释放掉局部变量,从而暂时保证了局部变量不会被销毁掉。
 
四,什么是形式参数?
       自定义函数中的“形参”全称为"形式参数" 由于它不是实际存在变量,所以又称虚拟变量实参和形参可以重名。
       是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
       形式参数就像其名字一样,这个变量只是一种形式,它不是实际存在的变量,可以是任意类型的变量,这个主要看调用函数是传入参数的类型。
实例:
function test(a,b,c){
  console.log(a);
  console.log(b);
  console.log(c);
}
test(1,2);//打印如下
//1
//2
//undefined
 
test(function(){alert()},{key1:'111',key2:'222'});//打印如下
//function(){alert()}
//{key1:'111',key2:'222'}
//undefined
 
从上面可以看出形式参数a,可以是number、function、object等等类型。
 
五,变量的赋值运算符“=”
 
在JavaScript中,变量有两种类型——值类型、引用类型。

(1)值类型:数值、布尔值、null、undefined。

(2)引用类型:对象、数组、函数。

1,值类型赋值。

实例:

var a = 1;

var b = a;

b = 2;

console.log(a);//1

console.log(b);//2
解释:
var b = a。值类型变量,在内存中都是为每一个变量分配一块内存空间,所以变量a、变量b相互不受影响。
2,引用类型赋值。
实例:
var obj1 = {a:'aaaaaa',b:'bbbbbb'};
var obj2 = obj1;
obj2.a = '111111';
console.log(obj1);//{a:'111111',b:'bbbbbb'}
console.log(obj2);//{a:'111111',b:'bbbbbb'}
console.log(obj1 === obj2);//true
解释:
     上面代码可以发现obj1和obj2是关联在一起的,改变obj2(或者改变obj1)obj1也会跟着改变。其实这里涉及到JavaScript变量——栈内存or堆内存的问题(详情请看这篇博客点击)。变量obj1和obj2其实都是一个指向同一块内存空间的地址,而在这块内存空间存储的引用类型变量是共用的。obj2改变它指向的引用类型变量,obj1也会跟着改变。
注:这个很重要,一定要弄清楚值类型、引用类型赋值。重点从上面给出的博客《JavaScript变量——栈内存or堆内存》这里突破。
3,引用类型'隔断'关联的方法(其实就是给引用类型各自分配一个内存空间)。
(1)利用JSON.parse和JSON.stringify这两个方法转换一下。
实例:
var obj1 = {a:'aaaaaa',b:'bbbbbb'};
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.a = '111111';
console.log(obj1);//{a:'aaaaaa',b:'bbbbbb'}
console.log(obj2);//{a:'111111',b:'bbbbbb'}
console.log(obj1 === obj2);//false
解释:
这里是现将引用类型变量obj1转换值类型字符串,然后在转换成引用类型赋值给obj2,这个时候obj1和obj2指向的引用类型是在内存中分配了两块内存。
(2)利用深度遍历
var obj1 = {a:'aaaaaa',b:'bbbbbb'};
var obj2 = {};
for(key in obj1){
   obj2[key] = obj1[key];
}
obj2.a = '111111';
console.log(obj1);//{a:'aaaaaa',b:'bbbbbb'}
console.log(obj2);//{a:'111111',b:'bbbbbb'}
console.log(obj1 === obj2);//false
 
 
 
 
 
 
 
 
 
posted @ 2016-05-03 14:45  minimal虾米  阅读(145)  评论(0编辑  收藏  举报