前端--關於javascript對象

来源:http://www.cnblogs.com/jinjilin/archive/2016/01/27/5160121.html
-Advertisement-
Play Games

在javascript中對象是一種基本的數據類型,在數據結構上是一種散列表,可以看作是屬性的無序集合,除了原始值其他一切都是對象。它可以用來表示現實世界中或者我們大腦中抽象出來的客體,這和其他面向對象的編程語言有些類似,但js並不是面向對象的而是基於對象的,因為典型的面向對象要求封裝、繼承和多態,而


  在javascript中對象是一種基本的數據類型,在數據結構上是一種散列表,可以看作是屬性的無序集合,除了原始值其他一切都是對象。它可以用來表示現實世界中或者我們大腦中抽象出來的客體,這和其他面向對象的編程語言有些類似,但js並不是面向對象的而是基於對象的,因為典型的面向對象要求封裝、繼承和多態,而javascript中的對象只是做到了封裝,繼承和在繼承基礎之上的多態它是不能直接支持的,只能在原型鏈的基礎上儘量的模擬出來。又由於函數也是對象,也就是說它也是一種值,既然是值它就既可以作為參數傳入也可以作為返回值返回並以此來產生高階函數,所以js也可以進行函數式編程。

  javascript中關於對象的操作共有七種:創建對象、設置屬性、查找屬性、刪除屬性、檢測屬性、枚舉屬性、檢測實例,這七種操作涵蓋了關於對象的絕大部分知識點。

  • 創建對象

  js對象的創建一共有三種方法:對象直接量法、構造函數法、Object.create法。

   對象直接量是最簡單的創建方法,一個大括弧裡面加上用逗號分隔的名值對就搞定了,只是有些細節要註意,因為屬性名可以是包括空字元在內的任何字元,所以一個屬性名稱如果不是合法的標識符,則它必須要用引號括起來,如果是一個合法標識符的話,則屬性名可以不用引號括起來。假如所有的屬性名都用引號括起來的話,那麼這個對象也就是一個標準的JSON對象。JSON格式的要求就是屬性名要用引號括起來,JSON字元串也是一樣的,所以用ajax從後臺獲取的JSON字元串時它的屬性名一定要用引號括起來,否則用JSON.parse方法轉換為對象時會出錯。

   構造函數法就是用new關鍵字加上一個函數調用來返回一個對象。這個函數可以是內置函數也可以是自定義函數,返回對象的屬性初始化工作是在這個函數體內進行的,當執行到new的時候就已經創建了一個新對象了,函數體內的this被初始化為這個對象。這個函數體內不必有return語句,它是自動返回對象的,如果強制加入return語句,那麼除非return返回的是一個對象,否則返回其他任何值都是無效的,只是如果沒有初始化完就return會阻止後續屬性的初始化。那麼構造函數創建出來的對象和直接量返回的對象有什麼不同呢?首先構造函數創建的對象的屬性初始化實在函數體內進行的,有函數的地方就有閉包,有了閉包就可以讓對象擁有隱藏的私有變數,這在直接量中是做不到的。其次就是原型對象prototype(在javascript中每個對象都和另一個對象相關聯,這個相關聯的對象就叫做原型對象,在查找屬性的時候如果本對象沒有那麼就會查找它的原型對象,原型對象沒有再查找原型對象的原型對象,一直找到沒有原型對象為止,這就相當於該對象繼承了它的原型對象的屬性,而且這種繼承還是一種動態繼承),每個函數都有一個prototype屬性,用構造函數創造出來的對象的原型就是這個構造函數的prototype屬性指向的對象,而通過直接量返回的對象它的原型對象是Object.prototype對象。如果預設情況下沒有設置過構造函數prototype屬性,則該構造函數的prototype對象只有一個用for/in不可枚舉出來的constructor屬性,該constructor屬性的值是該構造函數本身,這也是一種通過constructor來判斷實例對象類型的方法原理。如果是用prototype={巴拉巴拉巴拉}來重寫原型對象,那最好在巴拉巴拉巴拉中加上constructor:createfun把這個constructor補上,這也是為什麼並不是所有對象都有constructor的原因。           Object.create方法也可以創建對象,它創建出來的對象的原型就是傳給Object.create方法的對象參數。如果想創建一個沒有任何原型的對象,只需把null傳進去:Object.create(null)。這種創建對象的方法是在ECMAScript5中才加入的,原來的版中只能構造函數模擬出來。  

  •  設置屬性
  •  查找屬性

  設置屬性和查找屬性之所以放到一起是因為它倆的寫法是一樣子的。語法都是.操作符和[]操作符,在查詢時如果存在屬性就返回相應的值,如果不存在就返回undefined,同樣在設置屬性的時候,如果存在屬性就重新覆蓋,如果不存在屬性就會在對象上創建新屬性並賦初始值。而.操作符和[]操作符是有些區別的,[]操作符裡面是一個字元串或者可以轉化為字元串的值,.操作符後面跟的是一個標識符,如果要動態的指定屬性名只能用[]操作符,因為操作符不可能是動態的。其中賦值的話如果原型中也存在相同的屬性名,那麼是不會對原型有影響的。

  •  刪除屬性 

  刪除屬性用delete操作符,後面跟要刪除的對象和屬性。刪除非原始類型的時候有一個特點,例如 a={y:{x:1}} b=a.y  delete a.y  因為b還是引用著{x:1}的,所以這個delete只是斷開了{x:1}和對象啊的關係,列印b.x還是等於1,這個y對應的對象並沒有刪除掉。

  • 檢測屬性

    檢測屬性就是判斷某個屬性是不是對象的存在屬性。首先是in操作符,in操作符左邊是屬性名稱字元串,右邊是對象,如果左邊的屬性存在在右邊的對象中則返回ture;其實直接通過查詢可以檢測屬性,例如 如果a.x!==undefined,那麼x就在對象a中,否則不在,這種方法有一個小缺陷,就是當x屬性的值本身就是undefined的時候就不靈驗了。對於以上的檢測方法,其實都會包含對象的原型屬性,所以如果對象本身沒有而原型上有那麼返回的也是true。所以要想區分屬性是否是對象本身的就要用到另外的方法:hasOwnProperty和propertyIsEnumerable。如果O.hasOwnProperty("x")為true,那麼就是說x是對象o的自有屬性,propertyIsEnumerable是hasOwnProperty的加強版,不但要求是自有屬性還要求屬性是可枚舉的才返回true。

  • 枚舉屬性

  枚舉屬性就是把對象中的可枚舉的屬性名字一一返回,一般對象的屬性都是可枚舉的,但內置的繼承方法一般都是不可枚舉的,例如toString。一般枚舉屬性用的是for/in語句,同樣該語句返回的屬性也是包括繼承的屬性的。如果想直接獲取到自有的可枚舉的屬性集合,可以使用Object.keys(),這個方法返回一個自由屬性的數組。同樣Object.keys還有一個加強版Object.getOwnPropertyNames,這個方法返回的不單單是可枚舉的自有屬性,還包括不可枚舉的自有屬性。

  • 檢測實例

  檢測實例就是判斷實例對象是否屬於某個類或者實例對象的類名是什麼。而什麼是類呢?在面向對象中類是一個產生對象的模板,在javascript中起到這種作用的是原型對象,所以可以說一個原型對象prototype屬性就是一個類。判斷實例對象是否是某個類,就是判斷實例對象是否繼承自某個原型對象,這樣就會出現不同的構造函數產生的對象屬於同一個類,因為這不同的構造函數的prototype屬性可能是同一個對象。判斷實例對象是否繼承某個原型對象的方法有兩個:isPrototypeOf、instanceof,例如Class.prototype.isPrototypeOf(o)、o instanceof Class,這兩種方法是有區別的,首先調用isPrototypeOf方法的要是一個原型對象而不能是一個構造函數對象,參數是實例對象;instanceof 的左操作數要是實例對象,右操作數必須是一個構造函數而不能是一個原型對象,如果兩個構造函數a、b的原型對象都是p,那麼用a構造出來的實例對象o用instanceof判斷 o instanceof b 其結果也是true,所以用instanceof判斷為true時,實例對象不一定是由該構造函數構造出來的。其實這兩種判斷方法都是判斷的原型鏈,不管是直接繼承還是在更遠的間接繼承,只要原型鏈上存在該對象就會返回true。

   以上兩種是能判斷實例對象是否屬於某個類,並不能直接獲取類名,要獲取類名只能用並不是總是有效的兩種方法:toString和利用constructor屬性。關於toString方法,首先要清楚一點的就是每個對象都有一個類屬性,這個屬性的值是一個字元串來表明該對象是什麼類型,很遺憾這種類屬性是不能認為設定的,js沒有提供相應的介面,只能查詢到,而查詢的方法就是最原始的toString方法。最原始的toString方法指的是Object.prototype中的toString方法,因為很多其他對象都是繼承了該原型並且是重寫toString方法了的,所以直接調用對象的toString方法一般是查不到類屬性值的,所以只能借用Object.prototype中的toString方法。寫法如下Object.prototype.toString.call(o)。這樣返回的是一個類屬性字元串,該字元串有其特有的固定格式,例如"[object Array]",所以要只要截取第8個到倒數第二個字元即可,slice(8,-1)。通過toString方法獲得的類型名稱只是適用於內置對象的,像Date、Array等,而對於自定義對象,由於沒有提供設置類屬性的介面,不能重寫,自定義對象的類屬性都是一個值"[object Object]",看不出其所屬的類別。所以要獲取自定義屬性的類名就要用到constructor屬性。用constructor屬性判斷最好是那種構造函數和原型對象是一一對應的那種情況,如果不是一一對應的會讓本來相同類的不同對象看起來是不同類的,因為constructor獲取的不是原型對象而是構造函數對象的名字。這裡又會產生一個問題,就是不一定所有對象有constructor,就像前面說過的,同時也並不是所有的構造函數都有名字,像不帶名字的函數表達式就沒有名字,這就是這種判斷方法的一個不總是有效的原因。

   除了以上關於對象的操作還有對象的序列化,對象的序列化和反序列化就是JSON對象和JSON字元串之間的相互轉換,用到的方法有JSON.parse和JSON.stringify這兩種。其他的像getter/setter屬性的設置、對象的可擴展性、屬性的可枚舉性等感覺現在不是非常普及,先知道瞭解,以後隨用歲隨學吧。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實現情況: 可自主註冊, 登陸系統可購物,充值(暫未實現),查詢餘額。 擼了兩天一夜的代碼,不多說,直接上碼,註釋神馬的後面再說 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 shopping_list = [ 4 ['Iphone 6s pl...
  • http://www.tuicool.com/articles/MzayMri 電腦剛出世時,編程卡片為八十列;無獨有偶,Unix 早期的終端,每行最大顯示字元數也為八十個;Unix 大多文本工具也沿襲了這傳統,至今在 Maillist 上可以看到不少資深 Linux 工程師習慣把郵件正文 wra...
  • 在之前的Java技術彙總文章里,向大家介紹了Java入門學習的基礎資料,今天小編彙總了5篇Java技術進階實操的乾貨,趕緊來看看吧!另外,喜歡寫博客的工程師博主可以加工程師博主交流群:391519124,分享你的博文,和大牛們一起交流技術~一、Stack Overflow 上人氣爆表的10個 Jav...
  • 寫爬蟲之前,首先要明確爬取的數據。然後,思考從哪些地方可以獲取這些數據。下麵以一個實際案例來說明,怎麼尋找一個好的爬蟲策略。(代碼僅供學習交流,切勿用作商業或其他有害行為) 1).方式一:直接爬取網站 目標網址:http://chanyouji.com/ 註意:這個網站會攔截IP,訪問次數過多...
  • 背景 今天的分享主要來自我之前的工作經驗以及平時的學習總結和思考。我之前的背景主要是做框架、系統和平臺架構,之前的工作過的公司eBay、攜程、唯品會都是平臺型互聯網公司,所以今天主要帶著平臺架構視角和大家分享心得體會。架構的視角每個人都不一樣,可以說一萬種眼光,有業務架構、安全架構、平臺架構、數據架
  • NodeJS新手攻略 1、在官網(https://nodejs.org/)下載node安裝包進行安裝windows和Linux 版本都有 這裡說下windows系統安裝 安裝nodeJS直接下一步 安裝過程中可選擇安裝路徑 node -v npm -v 直接cmd使用nodejs命令查看是否安裝成功
  • JS 變數提升 函數提升
  • 淺析XMLHttpRequest
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...