1. 程式人生 > >在JavaScript中一切都是物件嗎?

在JavaScript中一切都是物件嗎?

原文連結:http://web.jobbole.com/82016/

“在JavaScript中的一切都是物件”這個說法一直讓我困惑。他們指的是什麼?一個函式或者陣列,它們怎麼同時也是一個物件?在我們解答這個問題前,我們需要知道JavaScript是如何對不同資料型別歸類的。

資料型別

在JavaScript中,有兩個資料型別:基本型別和物件型別(物件型別有時候也被稱為引用型別)。

基本型別

Number, String, Boolean, null, undefined

物件型別

Function, Object, Array

根據這個分類,這個問題的簡單答案是:JavaScript中,並非一切值都是物件。是隻有屬於物件型別的值才是物件。也可以認為,任何非基本型別的都是物件型別。但是基本型別和物件型別有什麼區別呢?更重要的是,人們所說的“所有”或“幾乎所有”的JavaScript類似都是物件的真正含義是什麼?這裡說說主要的兩個區別:可變性和比較。

Mutability可變性

根據我的經驗,人們說的值是“類似物件”的真實含義是因為他們的可變性,更具體的說,是支援新增和刪除屬性。例如,因為函式和陣列屬於物件型別,你可以像物件一樣給它們新增屬性。

var func = function() {};
func.firstName = "Andrew";
func.firstName; // "Andrew"

var arry = [];
arry.age = 26;
arry.age; // 26

可變性開啟了各種精彩的使用方式,也是理解原型和建構函式是如何工作的關鍵。

但是基本型別是不可變的,我們無法給它們新增屬性。如下面程式碼所示,即使我們給基本型別添加了屬性,解析器會無法在下一步讀取它們的值。

var me = "Andrew";
me.lastname = "Robbins";
me.lastname; // undefined

var num = 10;
num.prop = 11;
num.prop; // undefined

在這一點上,基本型別的值無法改變的真正含義,需要在更基本的層面檢查問題,如下程式碼所示:

1 = 2; // ReferenceError

這似乎是一個愚蠢的例子,但是我認為能反映出我們現在討論的可變性,當你在JavaScript控制器中輸入數字 1,編譯器會給其分配基本型別,所以當你嘗試將數字1改變成數字2會失敗。

比較和傳遞

除了可變性,另外一個基本型別和物件型別重要的區別是他們在程式中比較和傳遞的方式。基本型別通過值來比較,而物件型別通過引用來比較,這是什麼意思呢?我們先看看基本型別,如下程式碼所示:

"a" === "a"; // true

因為值“a”等於“a”所以為true,當我們在圖中引入變數會發生什麼呢?除了將一個基本型別儲存在變數中什麼也沒發生。

var a = "a",
    b = "a";

a === b; // true

當基本型別通過值來比較,結果為true,變數a的值正好等於變數b的值,換句話說,”a”等於”a”。但是看看下面這個例子,如果我們在物件型別中應用相同的例子,我們會得到相反的結果。

var a = {name: "andrew"},
    b = {name: "andrew"};

a === b; // false

為什麼會這樣呢?如果想要兩者比較為真需要物件型別要引用同樣的型別。通過以上的例子,我們給變數b建立一個新的物件。就像David Flanagan說過:我們說的通過引用進行物件比較是:兩個物件的值是否相同取決於它們是否指向相同的底層物件。

那我們這樣傳值會發生什麼?

var a = {name: "andrew"},
    b = a;

b.name = "robbins";

a === b; // true

這個可能開始看上去很奇怪,但是仔細看看發生了什麼,因為物件是物件型別的一部分,它比較的值是按引用進行傳遞。引用的是相同的底層物件。在以上的例子中,我們設定b等於a。並沒有建立新物件,我們只是簡單地建立了一個對其他物件的引用。從另一個方面來看我們是將變數b指向a,所以當我們改變b的name屬性,我們同樣改變了a的name屬性。

如果將相同的例子應用在基本型別上呢?

var a = "Andrew",
    b = a;

b = "Robbins";

a === b; // false

當我們設定b等於a,請記住基本型別通過值來傳遞和比較,我們實際上另外建立了一個a的拷貝,所以我們改變b的值再跟a比較,兩個值是不一樣的。

Wrapper Objects包裝物件

有些人會說:“好,如果基本型別不是物件,為什麼我們可以呼叫他們的方法呢” 回答是包裝物件。

當你嘗試呼叫基本型別的方法,JavaScript在幕後做了一個巧妙的處理,將你的基本型別的值轉換成臨時物件用於建構函式,決定使用哪個建構函式取決於你嘗試改變的基本型別的值,在String中呼叫.length會使用string()建構函式臨時將基本型別轉變成物件—允許你使用length方法而改變它,這個臨時物件被稱為包裝物件。

有趣的是,null和undefined這兩個基本型別不能呼叫這樣的方法,否則會提示型別錯誤。

我們可以使用typeof來區分:

typeof "s"; // "string"
typeof new String(s); // "object"

備註:在執行typeof null 時js編譯器會返回object,是顯而易見的bug。

typeof null // "object"

此外,我們也需要了解基本型別的屬性是隻讀和臨時的。

var hello = "hello";
hello.slice(1); // "ello" (Here we're actually calling slice not on hello, but of a copy of hello)
hello; // "hello"

Summary總結

JavaScript的值可以分為兩種型別:基本型別和物件型別,基本型別有:String, Number, Boolean, Symbol, undefined 和 null.,物件型別有Function, Object 和 Array.

基本型別和物件型別的區別在於可變性和比較的方式以及程式中傳值。

基本型別是不可變的,換種說法就是它們的值不能改變。對比而言,物件型別是可變的,它們的值可以更新和改變。

基本型別可以按值比較,當我們把一個基本型別賦值給另外一個基本型別,是複製了一個值。而物件這是通過引用進行比較,引用的是什麼呢?引用的是底層物件。當我們賦值一個物件給另一個物件時。引用指標就建立了。在這個情況下,改變一個物件的值將更新另外一個物件的值。

當我們嘗試在基本型別的值中呼叫方法時,JavaScript使用包裝物件來臨時控制基本型別,導致物件變為只讀的並在垃圾回收後執行。

相關推薦

JavaScript一切物件

原文連結:http://web.jobbole.com/82016/“在JavaScript中的一切都是物件”這個說法一直讓我困惑。他們指的是什麼?一個函式或者陣列,它們怎麼同時也是一個物件?在我們解答這個問題前,我們需要知道JavaScript是如何對不同資料型別歸類的。資

從函式的引數傳遞來理解python一切物件

From Python 初學者: a = 2 其中2為物件,a可理解為貼在物件上的標籤。 物件由不可變物件和可變物件,不可變物件有數字、字串、元祖,可變物件有列表,字典,集合。 def f(x): x *= 2 a = 1 f(a) print(a) #1 b =

JavaScript的Date物件在Safari與IOS 日期出錯

首先我需要的展示的時間格式是這樣的2018/03/06 下面這個是開始時間 replace(/\-/g, "/"); 轉化成我想要的格式 $scope.endtime = $stateParams.endtime.replace(/\-/g, "/"); 下面這個是結束時間&n

JavaScript的window物件 (狀態列動態文字例項)

window物件在js中經常會提到, 在具體瞭解之前經常會感覺疑惑, window到底是個啥, 這篇就是用來介紹window給和我一樣的菜鳥 Window - 瀏覽器物件模型 為什麼說瀏覽器物件呢? 因為window物件它表示瀏覽器窗口或一個框架, 與windows作業系統沒啥關係

javascript 獲取json物件的鍵構成的陣列

<!DOCTYPE html> <html>     <head>         <meta charset="utf-8">    &nb

Javascript 的Object物件

Object:物件屬於複合的資料型別,在物件中可以儲存多個不同資料型別的屬性。 物件是動態的,可以新增屬性也可以刪除屬性。 物件的常見用法: 建立、設定、查詢、刪除、檢測、列舉 物件的分類: 1.內建物件:是由ECMAScript規範定義的物件。如:陣列、函式、日期和正則表示式。 2.宿主物

javascript怎麼判斷物件{}為空

時候通過AJAX方法呼叫返回的是一個JSON物件,而這個物件可能在開發過程中會沒有資料是一個空{}。 JavaScript判斷object/json 是否為空,可以使用jQuery的isEmptyObject()方法。 function isEmptyObject(obj) {

javascript 獲取json物件的鍵構成的陣列

<!DOCTYPE html> <html>     <head>         <meta charset="utf-8">         <title></title>     </head

javascript的window物件的知識點

javascript中的window物件的知識點 內建物件定義:可以不需要宣告和建立,可以直接使用,內建物件全部為javascript關鍵字 window是內建物件,因為window使用的太頻繁了,所以一般window可以省略不寫,我們平時用的alert()其本質就是window.ale

JavaScript 建立一個物件

在JavaScript當中建立一個物件有兩種語法, 一種是通過字面量的形式,另外一種是通過new Object()的形式 建立一個person物件 它有 name,age,sex等屬性。 1.字面量形式(literal syntax) var person =

javascript對一個物件陣列按照物件某個屬性進行排序

在javascript中,物件和陣列是兩種不同的型別,這和php中的陣列概念不同。在javascript中,也有一些精妙的演算法,用來對一些物件進行排序。我在面試迅雷的時候,也拿到一道題,當時做題的時候考慮到時間,沒有去仔細研究,回來後再讀了一些方法,就知道真正的考點在哪裡了。 我們現在有一組“學

javascript函式、物件、原型鏈等的深入自我理解

js中以物件為核心,所有皆物件。 狹義的講,js中的物件比較純粹,就是一個大括號包裹的鍵值對,鍵為名(有待深入解析,可能就是語法本身),值為物件。 這個基本要素和C++比較接近,並沒有憑空創造出新的語法來完成這個物件(類)的構造過程。 函式本身是物件,可以作為物件中的值

原生javascript的arguments物件的重要應用

在arguments中,存在函式中、第1個引數的屬性名是’0’,第2個引數的屬性名是’1’,以此類推,並且它還有length屬性,儲存的是當前傳入函式引數的個數,很多時候我們把這種物件叫做類陣列物件(偽陣列) function test (a,b,c){ console.log(a,b,c)

javascriptnew Date()物件和getTime()方法的問題(又是來提問,(-__-)b)

昨天到現在一直在完成一個用canvas實現的倒計時的小案列,用到Date物件和getTime方法來計算倒計時的時間。老是有問題,不知道怎麼回事。貼error: 昨天是2016年7月18日 endTim

通過一道筆試題淺談javascript的promise物件

因為前幾天做了一個promise物件捕獲錯誤的面試題目,所以這幾天又重溫了一下promise物件。現在借這道題來分享下一些很基礎的知識點。 下面是一個面試題目,三個promise物件捕獲錯誤的例子,返回結果有什麼不同。 //使用throw新增錯誤事件 var p =

JavaScript的陣列物件屬性和方法!

日常程式碼中經常會對程式碼進行一些操作,複製、排序、查詢、遍歷等等,一些陣列的方法總是記不住,所以寫篇日記總結一下。 1. 陣列的建立與賦值 建立一個數組,有三種方法。 下面的程式碼定義了一個

JavaScript的XMLHttpRequest物件

  1.什麼是 XMLHttpRequest 物件?     XMLHttpRequest 物件用於在後臺與伺服器交換資料。     XMLHttpRequest 物件提供了對 HTTP 協議的完全的訪問,包括做出 P

javascript陣列及物件的合併

合併陣列的方法:    1、陣列遍歷       var arr1 = [ 1,2,3,4 ];             var arr2 = [ 2,3,4,5 ];             for( var i = 0 ; i < arr1.length; i ++

【例項】javascript的window物件的onbeforeunload、onload、onunload的區別(在新版本的瀏覽器兩個關閉事件可能不會觸發)

onload是在頁面載入的時候觸發,與之相反onunload是在頁面關閉(解除安裝)的時候觸發,至於onbeforeunload是指頁面將要關閉的時候觸發(一般用於彈出是否確認關閉的時候) 上程式碼 <!DOCTYPE HTML PUBLIC "-//W3C//DT

認識Javascript的navigator物件以及檢測瀏覽器型別和版本,獲取瀏覽器版本號,檢測客戶端作業系統

Navigator物件包含了Web瀏覽器的基本資訊(如名稱,版本,作業系統等) 通過window.navigator方式可以引用該物件,並利用它的屬性讀取客戶端基本資訊 Navigator的5個主要屬性: appName:Web瀏覽器的名稱 appVersion:瀏覽器的