變量
變量就是保存數據的容器
命名
變量名:
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
原理:找出那些沒用的數據,打上標記,釋放其內存,周期性執行,標識無用數據的策略
標記清除:離開其作用域以后,會被清除
引用計數(不常用)