原型與繼承學習筆記1

来源:http://www.cnblogs.com/wangxiaosan/archive/2016/05/27/5535368.html
-Advertisement-
Play Games

淺談對象(本筆記中截圖和部分代碼取自慕課網視頻http://www.imooc.com/learn/277第四章對象) 面向對象原型鏈繼承這塊,應該算是javascript中最難理解的部分了,小弟腦子比較難轉彎,也是看了好久視頻,博文,慢慢的才有了自己的理解,現在記錄一下學習的內容和總結。首先第一節 ...


    淺談對象(本筆記中截圖和部分代碼取自慕課網視頻http://www.imooc.com/learn/277第四章對象)

面向對象原型鏈繼承這塊,應該算是javascript中最難理解的部分了,小弟腦子比較難轉彎,也是看了好久視頻,博文,慢慢的才有了自己的理解,現在記錄一下學習的內容和總結。首先第一節應該說說對象這個東西了,js中對象和其他語言還是有所不同的,現在切入正題,開始淺談對象。

    什麼是對象

定義(ECMA-262):無序屬性的集合,其屬性可以包含基本值、對象或者函數。

通過定義可以看出來,對象是屬性的集合,這些屬性又會是一個基本值,一個函數或者又是一個新的對象。記住,函數也是對象,瞭解這點以後原型鏈會很好理解。

 

    對象結構

大概解釋一下這個圖,var obj = {}; obj.x = 1; obj.y = 2;這段代碼先定義了一個obj空對象,然後定義了兩個屬性x和y,每一個屬性又都是一個鍵值對的對象。有writable,enumberable,configurable,value四個屬性和一對get/set方法。一個對象又有三個預設的屬性__proto__,__class__,__extensible__,其中__proto__屬性是指向創建該對象的函數(方法)的prototype對象,如第二個obj的__proto__對象會指向fn的構造函數的prototype屬性。好吧,有點繞,後續會繞出來的。。。

    創建對象

1.new

首先,需要說明的是,對象其實都是通過函數創建的,如上圖中的var obj=new fn();,再比如這種:var obj={},arr=[];,其實這兩種創建對象的方法的實質分別為var obj=new Object(),arr = new Array();,所以對象都是通過函數創建的這個話就不足為奇了。

上個模塊我們知道了函數會預設有prototype這個屬性,如下:

這個prototype的屬性值是個對象,即屬性的集合,該屬性一般情況下只有一個constructor屬性,指向函數本身。

我們也可以在自定義函數的prototype中添加一些屬性,看代碼:

1 function Fn(){
2 
3 };
4 Fn.prototype.x=1;
5 var f1 = new Fn();

 

這時,實例化的f1對象就可以訪問Fn()的原型屬性x的值了。也就是說,f1對象是從Fn函數new出來的,這樣f1對象就可以調用Fn.prototype中的屬性了。這是因為每個對象都有一個__proto__屬性(chrome將這個屬性暴露了出來,大家可以在chrome瀏覽器上看一下這個屬性),這個屬性引用了創建該對象的函數的prototype屬性,可以得到f1.__proto__===Fn.prototype.__proto__會在下節詳細說明,這個算是原型鏈繼承的關鍵(一條看不見的鏈條連接了所有有血緣關係的家族~)。本節還是繼續扯函數的prototype屬性。

那麼原型這塊大體上可以用下圖來表示:

一句話概括:實例化出來的對象的__proto__屬性連接實例函數的prototype屬性,這樣實例化對象就可以通過看不見的那根鏈條訪問prototype屬性。那麼問題來了:怎麼判斷一個對象的屬性值是原型上的屬性還是自身的屬性,js為我們提供了這麼一個方法:hasOwnProperty()和in操作符,如上,使用in操作符可以判斷屬性是否存在(包含原型鏈上屬性),hasOwnProperty()方法也是判斷屬性是否存在(不包含原型屬性)。

2.Object.create()

根據代碼對比來理解一下:

 1 function Person (name) {
 2     this.name=name
 3 };
 4 Person.prototype.sayName=function(){
 5     console.log(this.name)
 6 };
 7 function Teacher(name){
 8     this.name=name
 9 };
10 Teacher.prototype = Person.prototype;
11 var teacher = new Teacher("James");
12 teacher.sayName();       //James
13 
14 Teacher.prototype.teach = function(course){
15     console.log("I teach "+course)
16 }
17 teacher.teach("English");   //I teach English
18 
19 var person = new Person("Lebro");
20 person.teach("Chinese");    //I teach Chinese

 

 

如上第10行代碼,將Person的原型直接賦值給Teacher的原型看似是沒問題的,對象teacher會繼承Person()的sayName()方法,但是給Teacher拓展方法時就會出現共用的問題,Teacher.prototype 會和 Person.prototype指向一處引用,這樣拓展Teacher的原型方法就相當於給Person的原型添加了方法,顯然不是我們想要的;

所以引入了Object.create()方法免除這個問題,實質還是對prototype屬性的賦值:

 1 function Person (name) {
 2     this.name=name
 3 };
 4 Person.prototype.sayName=function(){
 5     console.log(this.name)
 6 };
 7 function Teacher(name){
 8     this.name=name
 9 };
10 Teacher.prototype = Object.create(Person.prototype);
11 var teacher = new Teacher("James");
12 teacher.sayName();       //James
13 
14 Teacher.prototype.teach = function(course){
15     console.log("I teach "+course)
16 }
17 teacher.teach("English");   //I teach English
18 
19 var person = new Person("Lebro");
20 person.teach("Chinese");    //Uncaught TypeError: person.teach is not a function

 

 如上代碼,用Object.create()方法代替直接賦值就會避免這個問題,因此這個方法實際上就是先創建一個空對象,把參數Person.prototype的值有這個空對象進行傳遞給Teacher.prototype,這樣就不會有原型共用的問題了,使用Object.create()方法時考慮到這一點就不會出錯了(沒有研究源碼,只是本人暫時這麼理解的,歡迎指正)。

    第一節就先說這麼多,沒有按照常用思維來寫,因為本次執筆只是本人的一次學習總結,是按照我從不懂到慢慢縷清整個思路的一個過程來寫的,可能不會滿足所有人的學習模式,而且最基礎的一些對象方面的知識也沒提到,因為能看到原型繼承這塊我覺得最基本的基礎應該是具有的,所以,請盡情吐槽吧~~~下節說一下對象的屬性操作,包括讀寫,刪除,枚舉,檢測。下節再見了。

    原型與繼承學習筆記2  http://www.cnblogs.com/wangxiaosan/p/5535606.html


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

-Advertisement-
Play Games
更多相關文章
  • 要改前人用的flexslider功能,但苦於找不到詳細的文檔教程,折磨了好久……(所以我才說不愛亂用插件) 為了福利下之後也苦於這個問題的人,我整理總結了下我找到的一些東西。可能沒那麼完善正確,歡迎在留言補充 ☆基礎使用☆ 英文什麼的,我才不想看咧……照著1234就好 https://www.woo ...
  • https://daveceddia.com/access-control-allow-origin-cors-errors-in-angular/ Getting this error in your Angular app? No ‘Access-Control-Allow-Origin’ he ...
  • 由於系統預設alert彈出視窗不能自定義樣式,有可能不符合網站的風格,雖然網上應該有很多這樣的JS 但是還是自己寫的比較放心,順便練習一下對DOM的操作 支持IE6下的SELECT不能遮罩的問題,谷歌支持圓角,IE6下就比較醜了,四四方方的,不過可以自定義自己喜歡的樣式 聽取建議後,修改了posit ...
  • 按步驟安裝--選擇指定瀏覽器-安裝成功後顯示綠色圖標; 打開瀏覽器;將文件夾移入wampserver安裝路徑的www文件夾中;找到電腦IP 在手機端訪問 IP/文件夾/demo.html即可 ...
  • 上節我們討論了對象的定義和對象的創建,知道了函數也是對象,知道了對象都是由函數創建的,知道了對象的原型和函數的原型屬性的關係。這節說一下關於對象屬性的操作,下節就可以切入正題了。 屬性刪除 delete操作符刪除一個屬性值後會返回true,第5行也返回true是因為person.age已經是個und ...
  • 1.XPath 查看元素的xpath https://addons.mozilla.org/zh-CN/firefox/addon/xpath-checker/ 2. Tamper Data 查看頁面每一個請求的具體響應時間,結果 https://addons.mozilla.org/zh-CN/f ...
  • (1) 先說jquery, 使用 jQuery 庫的話,只需要同時綁定 oninput 和 onpropertychange 兩個事件就可以了,示例代碼: $('#username').bind('input propertychange', function() { $('#content').h ...
  • 在開發的時候,遇到了這樣一個問題,客戶填寫自己的收貨地址,可以新建,但同時也可以選擇之前填寫的,由於我們的客戶本身就是商戶,地址繁多,把它之前的地址簡單用個下拉框羅列出來顯然不合適,並且客戶要求能夠對地址通過姓名篩選,這樣,選擇地址就必須再開一個小窗來完成了,那麼,小窗中填寫的值怎麼回傳呢? js有 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...