創(chuàng)建一個變量并使其賦值,這一過程是什么樣子的?
通常這一個過程我們用一條語句實現(xiàn),如下:
var num1=5;
這當中解釋器發(fā)什么了很多的操作
- 創(chuàng)建了num1這個名字
- 創(chuàng)建num1變量需要var,定義一個它可以訪問或者被操作的范圍,也就是它的作用域.
- 把var num1這個操作提升到函數(shù)的最頂上
- 判斷5是什么數(shù)據(jù)類型,5是Number,屬于基本類型,把5的值保存在num1當中(棧內(nèi)存中)
image.png
var obj1=new Object();
創(chuàng)建對象過程和上面類似,只不過對象的值保存在堆內(nèi)存當中,而把內(nèi)存的地址(引用)保存在obj1當中。
image.png
屬性方法的增刪修改操作
基本數(shù)據(jù)類型:
- 增刪沒有任何作用,不會報錯。
- 變量的修改,相當于變量重新賦值
例如var num1=5 ---> var num1="123" 相當于把num1這個變量銷毀掉,重新創(chuàng)建一個變量num1出來,在把值"123"保存到變量中
引用數(shù)據(jù)類型·:
- 可以屬性方法的增刪
- 如果給變量賦值相當于重新創(chuàng)建一個變量
- 如果是修改某一屬性,解釋器會順著變了保存的內(nèi)存地址,找到堆內(nèi)存的值然后進行修改。
復制變量值
基本數(shù)據(jù)類型:
var num1=123;
var num2=num1;
- 創(chuàng)建了一個變量num2,給num2進行賦值的操作
- 創(chuàng)建num2和num1是相互獨立的
引用數(shù)據(jù)類型:
var obj1=new Object();
var obj2=obj1;
- 創(chuàng)建obj2,給obj2進行賦值操作,只是把obj1的內(nèi)存地址復制一份給obj2
函數(shù)的參數(shù)傳遞
- js解釋器對于參數(shù)類型是不關心的
function add(a,b){
return a+b
}
a,b可以為number,string等等
- 參數(shù)是以數(shù)組的形式傳遞的,參數(shù)的數(shù)量就無所謂了。
function add(){
return arguments[0]+arguments[1]
}
- 參數(shù)的一個作用,方便使用。。。
- 當一個變量進行函數(shù)參數(shù)傳遞的時候,這個時候所有參數(shù)都是按值傳遞。
基礎數(shù)據(jù)類型:count=20,傳參的時候, 相當于將20賦值給num,所以count和num是毫無關系的,互不影響。
引用類型:
函數(shù)外的變量是全局變量,而復制出的參數(shù)是局部變量,作用范圍是函數(shù)內(nèi)部,這和復制引用類型是完全相同的,事實并不是這樣。。。
本質(zhì):
- 對局部變量的屬性進行修改,過程是這樣子,首先解釋器先訪問局部變量,發(fā)現(xiàn)是引用類型,通過引用找到堆內(nèi)存的值進行修改,這種修改對外部變量保存的引用沒有任何影響,只不過函數(shù)里面修改堆內(nèi)存值的時候,外部變量保存的還是這個內(nèi)存,所以內(nèi)部修改,外部就修改
- 直接對局部變量本身進行修改,對obj進行修改,obj指向不是原來的堆內(nèi)存,而是另一個,這個時候它變成了一個新的局部變量,它的作用范圍就是定義這個函數(shù)的作用范圍,而且在這個函數(shù)執(zhí)行完事,這個局部變量就銷毀掉了。
function addTen(num){
num+=10
return num
}
var count=20;
var result=addTen(count);
alert(count) //20 無變化
alert(result) //30
function setName(obj){
obj.name="zhx" //內(nèi)部變量
}
var person = new Object() //外部變量
setName(person)
alert(person) // "zhx"
function setName(obj){
obj.name="zhx"
obj=new Object()
obj.name="xxx"
}
var person = new Object() //外部變量
setName(person)
alert(person) // "zhx"