JavaScript-进阶篇(一)之变量

2017-06-01  本文已影响0人  greenteaObject

变量

变量就是保存数据的容器

命名

变量名:
1.$ _ 字母 数字,数字不能开头
2.区分大小写
3.关键字: if for...
保留字: class...

声明
var score;
score = 4;

var score = undefined;
score = 4; 

var score = 4;

var aScore = 8;
var bScore = 1;

var aScore = 8,
    bScore = 5;
数据类型

基本类型 : 4 'str' true/false undefined null
引用类型 : [] {}

区别:基本类型值不会改变,引用类型会改变

var num = 6;
num = 5 //覆盖
var person = 'person';
person.name = 'xiaoming';
console.log(person.name);   //undefined
堆栈
image.png
基本类型保存在栈中,栈的空间的是有序且大小固定的,而堆中是大小不固定且无序的.在栈中保存的引用类型是一个引用地址
相等比较
var a = 4;
var b = 4;
console.log(a === b);   //true

var xm = {
    age:18,
    scroe:4;
};
var xh = {
    age:18,
    score:4
}
console.log(xm === xh);     //false

由于对象之间的比较是判断的地址是否相等,每个地址开辟了不同的堆内存空间,因此只有当两个变量是同一个对象的引用时,才相等

var xm = {
    age:18,
    scroe:4;
};
var xh = xm;
console.log(xm === xh);     //true 
function equal(a,b){
    for(var p in a){
        if (a[p] !== b[p]) return false;
    }
    return true;
}
console.log(equal(xm,xh));      //true
复制变量的值
var xm = 4;
var xh = xm;
xm++;
console.log(xm);    //5
console.log(xh);    //4
参数传递
//基本类型的参数传递
function addTen(){
    return num + 10;
}
var score = 10;
console.log(addTen(score));     //num = score;
//引用类型的参数传递
function setName(obj){
    return obj.name = 'xm';
}
var person = {}
setName(person);
console.log(person.name);    //obj = person 传递了对象地址的值
function setName(obj){
    obj.name = 'xm';
    obj = {};   //此时的Obj不再是person
    obj.name = 'xh';
}
var person = {};
setName(person);
console.log(person.name);   //xm
检测类型
//typeof
console.log(typeof 3);      //number
console.log(typeof 'str');      //string
console.log(typeof true);       //boolean
console.log(typeof undefined);      //undefined
console.log(typeof null);       //object
console.log(typeof []);     //object
console.log(typeof {});     //object
console.log(typeof function(){});       //function
console.log(typeof /a/ );       //object
//instanceof      只能和引用类型使用
console.log([] instanceof Array);   //true
console.log([] instanceof Object);  //true
console.log({} instanceof Object);  //true
console.log({} instanceof Array);   //false
全局作用域和局部作用域
var name = 'greentea';    //全局作用域的生命周期在脚本执行完毕才会销毁
function fn(argument){
    var sex = 'male';    //局部作用域在函数执行结束即销毁
}
fn();

没有块级作用域

变量对象和作用域链
var name = 'xm';
function fn(){
    var sex = 'male';
    var name = 'xh'
    function fn2(){
        var name = 'xhei'
        var age = 18;
    }
}
console.log(window.name === name);      //true

全局作用域的变量对象是window,而局部作用域的变量对象是显示不出来的.
查找变量先从当前作用域中查找,如果没有向上一层查找

预解析
var name = 'xm';
var age = 18;
function fn(){
    console.log(name);  //undefined
    var name = 'xh';
    var age = 10;
}
fn();

JS的解析过程:
1.预解析
由全局向局部预解析.首先,将所有的变量var赋值undefined.然后将函数声明
如果变量名和函数名相同,则只存在函数名
2.逐行解读代码

解析机制详解

问题一:

//1
console.log(b);      //undefined
var b = 1;

//2
console.log(a);      //报错
a = 1;

预解析先去找var,因a没有var,导致报错

console.log(a);
var a = 1;
console.log(a);
function a(){
    console.log(2);
}
console.log(a);
var a = 3;
console.log(a);
function a(){
    console.log(4);
}
console.log(a);
a();

//预解析先会将var a = undefined,但是又有a的function,因此,a变量被function替代,只剩下function a.
//然后a被赋值为1,3...最后执行a(),因为a被赋值后是变量,所以会报错
var a = 1;
function fn(){
    console.log(a);     //undefined
    var a = 2;
}
fn();
console.log(a);
//首先预解析var定义undefined,在fn()中的预解析中a定义为undefined.因此a为undefined
var a = 1;
function fn(){
    console.log(a);     //1
    a = 2;
}
fn();
console.log(a);     //2
//里面没有var,就在外面去找,然后a = 2是全局的,因此为2
var a = 1;
function fn(a){
    console.log(a);     //undefined
    a = 2;
}
fn();
console.log(a);     //1
//参数相当于var
var a = 1;
function fn(a){
    console.log(a);     //1
    a = 2;
}
fn();
console.log(a);     //1
//传进来以后是全局变量了
垃圾回收机制

释放无用的数据,回收内存

自动:JS
手动:Objective-C
原理:找出那些没用的数据,打上标记,释放其内存,周期性执行,标识无用数据的策略
标记清除:离开其作用域以后,会被清除
引用计数(不常用)

上一篇 下一篇

猜你喜欢

热点阅读