1.**ECMAScript中的所有參數傳遞的都是值,不可能通過引用傳遞參數。**
2.**五種基本數據類型是按值訪問的**,因為可以操作保存在變量中的實際值。引用類型的值是保存在內存中的對象。與其他語言不同,JavaScript不允許直接訪問內存中的位置,也就是說不能直接操作對象的內存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。因此,**引用類型的值是按引用訪問的。(實際上這種說法并不嚴密,當復制保存著對象的某個變量時,操作的是對象的引用。但在為對象添加屬性是,操作的是實際的對象。)**
3.對于引用類型的值,我們可以為其添加屬性和方法,也可以改變和刪除其屬性和方法。但是,我們不能給基本類型的值添加屬性,盡管這樣做不會拋出錯誤。這說明只能給引用類型動態地添加屬性,以便將來使用。
4.復制引用操作時,復制操作結束后,兩個變量實際上將引用同一個對象。因此,改變其中一個變量,就會影響另一個變量。
5.**ECMAScript中所有參數都是按值傳遞的。當我們給函數傳入參數時,實際就是把函數外部的值復制給函數內部的參數,這和把值從一個變量復制到另一個變量一樣。**
為了說明函數的參數是按值傳遞的,請看下面的例子:
~~~
function setName(obj) {
//相當于省略了var obj = person;
obj.name = ‘Nicholas’;
obj = new Object(); //重寫了obj的值,這時候obj與person引用的對象無關了。
obj.name = ‘Greg’;
}
var person = new Object();
setName(person);
alert(person.name); //‘Nicholas’
~~~
**個人理解:如果參數是按引用傳遞的話,那么obj和person應該始終指向同一個對象,實際上把person傳入到setName中只不過是把person指向的對象的指針副本復制給obj。給ECMAScript函數傳變量,相當于把外部變量賦值給函數內的局部變量。**
另一個面試中常見的陷阱:
~~~
var foo = {
bar: function(){return this.baz;},
baz: 1};?
(function(){return?typeof?arguments[0]();})(foo.bar); //undefined
~~~
相當于arguments[0] = function(){return?this.baz;}
6.***instanceof操作符用于檢測變量的具體引用類型***。如果變量是給定引用類型的實例,則返回true。
語法:result = variable instanceof constructor;
7.在Web瀏覽器中,全局執行環境被認為是window對象,因此所有全局變量和函數都是作為window對象的屬性和方法創造的。**某個執行環境中的所有代碼執行完畢后,該環境被銷毀,保存在其中的所有變量和函數定義也隨之銷毀**(全局執行環境直到應用程序退出--例如關閉網頁或瀏覽器--時才會被銷毀)。
8.延長作用域鏈的方法有兩個:
--try-catch語句的catch塊
--with語句
這兩個語句都會在作用域鏈的前端添加一個變量對象。對with語句來說,會將指定對象添加到作用域鏈中。對catch語句來說,會創建一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明。
9.JavaScript中沒有塊級作用域,因此if語句中的變量聲明會添加到當前的執行環境中。在使用for語句時尤其要牢記這一差異,例如:
~~~
for (var i=0; i <10; i++) {
doSomething(i)
}
alert(i); // 10
~~~
10.***優化內存占用的最佳方式,就是為執行中的代碼只保留必要的數據。一旦全局對象、全局對象屬性以及循環引用變量的引用不再有用,最好通過將其值設置為null來釋放其引用--這個做法叫做解除引用。這一做法適用于大多數全局變量和全局對象的屬性***。如下面這個例子所示:
~~~
function creatPerson(name) {
var localPerson = new Object();
localPerson.name = name;
return localPerson;
}
var globalPerson = creatPerson(‘Ken’);
globalPerson = null; //在不使用它的時候手工為它解除引用。
~~~
11.基本類型值在內存中占據固定空間大小,因此被保存在棧內存中;引用類型的值是對象,保存在堆內存中。