变量
变量就是保存数据的容器
命名
变量名:
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
堆栈
基本类型保存在栈中,栈的空间的是有序且大小固定的,而堆中是大小不固定且无序的.在栈中保存的引用类型是一个引用地址
相等比较
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
原理:找出那些没用的数据,打上标记,释放其内存,周期性执行,标识无用数据的策略
标记清除:离开其作用域以后,会被清除
引用计数(不常用)