JS中原型鏈的理解

  在談原型鏈之前,我們首先要了解自定義函數與 Function 之間是什么關系,而構造函數、原型和實例之間又存在什么千絲萬縷的關系呢?其實,所有的函數都是 Function 的實例。在構造函數上都有一個原型屬性 prototype,該屬性也是一個對象;那么在原型對象上有一個 constructor 屬性,該屬性指向的就是構造函數;而實例對象上有一個 _proto_? 屬性,該屬性也指向原型對象,并且該屬性不是標準屬性,不可以用在編程中,該屬性用于瀏覽器內部使用。

1    // _proto_
2 在函數里有一個屬性prototype
3 由該函數創建的對象默認會連接到該屬性上
4     //prototype 與 _proto_ 的關系
5 _proto_是站在對象角度來說的
6 prototype 是站在構造函數角度來說的

  下面,我們來看圖說話。

1、構造函數、原型和實例之間的關系
①+Object
②+Function+Object+Array

  

  了解這些之后,我們再來討論什么是原型鏈。說白了,其實就是有限的實例對象和原型之間組成有限鏈,就是用來實現共享屬性和繼承的。下面,我們看代碼說話。

 1    var obj = new Object();
 2 對象是有原型對象的
 3 原型對象也有原型對象 
 4    obj._proto_._proto_._proto_
 5 原型對象也有原型對象,對象的原型對象一直往上找,會找到一個null
 6 // 原型鏈示例
 7    var arr = [];
 8    arr -> Array.prototype ->Object.prototype -> null
 9    var o = new Object();
10    o -> Object.prototype -> null;
function Foo1(){this.name1 = '1';
}
function Foo2(){this.name2 = '2';
}
Foo2.prototype = new Foo1();
function Foo3(){this.name = '3';
}
Foo3.prototype = new Foo2();
var foo3 = new Foo3();
console.dir(foo3);

  接下來就是繼承問題了。

2、繼承 

 1)原型繼承

 1  function Animal(name){
 2        this.name = name;
 3    }
 4    function Tiger(color){
 5        this.color = color;
 6    }
 7 //   var tiger = new Tiger('yellow');
 8 //   console.log(tiger.color);
 9 //   console.log(tiger.name);  //undefined
10 //      Tiger.prototype = new Animal('老虎');   //一種方式
11    Object.prototype.name = '大老虎';   //第二種方式
12         var tiger = new Tiger('yellow');
13         console.log(tiger.color);
14         console.log(tiger.name);
??值得注意的是,這里存在兩個主要的問題:?①它不方便給父級類型傳遞參數;②父級類型當中的引用類型被所有的實例共享

????2)ES5 提供了Object.create() 方法來實現繼承

 1 ————做兼容
 2   //shim墊片
 3     function create(obj){
 4         if(Object.create){
 5             return Object.create(obj);
 6         }else{
 7             function Foo(){}
 8             Foo.prototype = obj;
 9             return new Foo();
10         }
11     }

  這種方法是ES5的新特性,其實就是復制繼承。

?  ?3)拷貝繼承
1 var obj = {};
2 obj.extend = function(obj){
3     for(var k in obj){
4       this[k] = obj[k];
5     }
6 }
???? 4)借用構造函數繼承
——被借用的構造函數中原型上的成員沒有被借過來
 1 function Animal(name){
 2     this.name = name;
 3 }
 4 function Mouse(nickname){
 5     Animal.call(this,'老鼠');
 6     this.nickname = nickname;
 7 }
 8 var m = new Mouse('杰瑞');
 9 console.log(m.name);
10 console.log(m.nickname);

?  存在的問題:可以解決原型繼承當中傳參問題,但是父類型當中的原型對象上的成員(屬性和方法)不能被繼承到

??  5)組合繼承
——prototype對象是有動態性的
 1 function Person(name){
 2    this.name = name;
 3 }
 4 Person.prototype.showName = function(){
 5    console.log(this.name);
 6 }
 7 function Student(name,age){
 8    Person.call(this,name);
 9    this.age = age;
10 }
11 Student.prototype = new Person();
12 Student.prototype.contructor = Student;
13 Student.prototype.showAge = function(){
14     console.log(this.age);
15 }
16 var stu = new Student('張三',12);
17 stu.showName();
18 stu.showAge();

【原型繼承+借用構造函數繼承】它的特點就是屬性每個實例一份,方法共享

?

【小結】套用一句很粗暴的話,所謂原型鏈就是找媽的一種行為方式,就可以理解為人是人他媽生的,妖是妖他媽生的。原型鏈的核心其實就只有一個:屬性共享和獨立的控制,當你的對象實例需要獨立的屬性,所有做法的本質都是在對象實例里面創建屬性。若不考慮太多,你大可以在Person里面直接定義你所需要獨立的屬性來覆蓋掉原型的屬性。總之,使用原型繼承的時候,要對于原型中的屬性要特別注意,因為他們都是牽一發而動全身的存在。現在最常用的方法是組合模式。

1、原型鏈

????1)構造函數、原型和實例的關系

? ??? ??①構造函數都有一個屬性prototype,這個屬性是一個對象(Object的實例)
? ??? ??②原型對象prototype里面有一個constructor屬性,該屬性指向原型對象所屬的構造函數
? ??? ??③實例對象都有一個_proto_屬性,該屬性也指向構造函數的原型對象,它是一個非標準屬性,不可以用于編程,它是用于瀏覽器自己使用的
????2)prototype與_proto_的關系

?

? ??? ??①prototype是構造函數的屬性

? ??? ??②_proto_是實例對象的屬性

? ??? ??? ??? ??? ? ——這兩者都指向同一個對象

? ??【總結】i)函數也是對象,對象不一定是函數;

????????????ii)對象的本質:無序的鍵值對集合;鍵值對當中的值可以是任意數據類型的值

????????????iii)對象就是一個容器,這個容器當中放的是(屬性和方法)

? ??3)屬性搜索

????  ①在訪問對象的某個成員的時候會先在對象中找是否存在

? ??  ②如果當前對象中沒有就在構造函數的原型對象中找

? ??  ③如果原型對象中沒有找到就到原型對象的原型上找

? ??  ④知道Object的原型對象的原型是null為止

2、Function

——所有函數都是Function的實例

? ??①本地對象:獨立于宿主環境(瀏覽器)的對象——包括Object、Array、Date、RegExp、Function、Error、Number、String、Boolean

? ??②內置對象——包括Math、Global(window,在js中就是全局變量),使用的時候不需要new

? ??③宿主對象——包括自定義對象、DOM、BOM

轉載于:https://www.cnblogs.com/DF-fzh/p/5619319.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271555.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271555.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271555.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

返利是什么意思

就是將錢返給你。 按消費金額的10%返利: 如果你消費1000元,返給你100010%100元;

計算機系統基礎:總線結構知識筆記

1、總線定義 計算機和設備之間傳輸信息的公共數據通道,是連接計算機硬件內多種設備的通信線路。它實現了總線上所有設備共享。 2、總線的分類 2.1 數據總線(DB) 用來傳遞數據信息,雙向的。數據總線的寬度決定了CPU和計算機奇特設備…

html引用c 變量,Y.A.K.E

記錄一次C項目改造中定義全局變量的操作.我對C/c不太熟悉,在修改別人項目的時候,想弄個文件,專門存放全局變量.然后各種不對.xxx previously defined here錯誤 或者 error: redefinition of xxx或者initialized and declared extern反正各種問題.其實根本原因就是重復引用導致的…

linux python開發環境_如何在Linux系統中搭建Python編程環境

1 在大多數的Linux系統中,基本上都默認安裝了Python,也就是說,在Linux的系統中基本上是不需要安裝什么軟件,就可以使用Python。 下面以ubuntu操作系統為例,看看如何在Linux操作系統中搭建Python編程環境。2 檢查Ubuntu…

CentOS 搭建 LAMP服務器

CentOS 7.0默認使用的是firewall作為防火墻,這里改為iptables防火墻。 1、關閉firewall: systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewall開機啟動 2、安裝iptables防火墻 yum install iptables-ser…

什么叫兜底條款

就是一個條款就能覆蓋所有未說到的內容:如:"其它應當受到處罰的行為." 有了這樣的條款,制度和法律才不會出現死角,讓一些人鉆空子,由于規定不可能十分周全,所心好多人還是在想方設法鉆空子.

當你的電腦C盤滿了怎么辦?這兩種方法都能解決

用了好幾年的電腦,在分區的時候C盤空間分的太小;有的喜歡把下載的軟件、工作時的文件都放在桌面上方便自己使用;有的安裝軟件的時候不選擇安裝目錄或一些軟件必須要安裝在C盤,這樣你的C盤的空間就會變得不夠,今天分享下…

一個html有幾個css,幾個CSS的黑科技_html/css_WEB-ITnose

原文出處: JellyBool(JellyBool) 歡迎分享原創到伯樂頭條昨天由于某些原因沒有寫博客,之前說好的每天一篇的,這篇是為了補昨天的了。然后我就要當一次標題黨了。這里的黑科技其實就是一些CSS中不怎么為人所知但在解決某些問題的時候很溜的屬性…

python遞歸函數講解_帶你深入學習Python——Python遞歸詳解!

一、遞歸 遞歸:在調用一個函數的過程中,直接或間接地調用了函數本身這個就叫遞歸 注:Python在遞歸中沒有像別的語言對遞歸進行優化,所以他的每一次調用都會基于上一次的調用進行,并且他設置了最大的遞歸數量防止遞歸外溢 遞歸調用…

51nod 1040最大公約數和(歐拉函數)

1040 最大公約數之和題目來源: rihkddd基準時間限制:1 秒 空間限制:131072 KB 分值: 80 難度:5級算法題收藏關注給出一個n,求1-n這n個數,同n的最大公約數的和。比如:n 61,2,3,4,5,6 同6的最大公…

計算機安全基礎:加密技術知識筆記

1、加密技術介紹 加密技術是最常用的數據安全保密的手段,加密技術的關鍵在于加密/解密算法和密鑰管理。 數據加密的過程:對明文文件或數據按照某種算法進行處理,變成密文。密文需要根據相應的密鑰才能獲得原來的明文信息,通過這種…

an導入html5,H5-FLASH:AN HTML5-BASED FLASH RUNTIME

摘要:Flash has been widely deployed to many internet applications.Nevertheless,as a closed development platform,there are more and more concerns arisen around its security and performance problems.On the other hand,HTML5 provides an alternative …

JAVA 獲取格林威治時間(GMT)

記錄下獲取GMT時間的方法: //格式可根據需要自定義,如yyyy-MM-dd HH:mm:ss 等等 SimpleDateFormat sdf new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss GMT", Locale.US); Calendar calendar Calendar.getInstance(); sdf.setTimeZone(Tim…

Linux CentOS下安裝Oracle

1 、在安裝oracle之前首先安裝以下組件包,直接輸入下列語句安裝。 yum install binutils* -y yum install compat-lib* -y yum install gcc* -y yum install glibc* -y yum install ksh* -y yum install libgcc* -y yum install libstdc* -y yum install libaio* -y…

計算機安全基礎:認證技術知識筆記

1、認證技術介紹 認證技術主要是用來解決網絡通信過程中通信雙方身份的認可。認證的過程涉及加密和密鑰交換。認證方一般都會有賬戶名、口令、使用摘要算法和基于PKI認證。 2、PKI系統介紹 PKI是一種遵循既定標準的密鑰管理平臺,能夠為所有的網絡應用提供加密和數字…

python 比例之差z假設檢驗_假設檢驗在數據分析中的應用

前言Z檢驗T檢驗獨立樣本t檢驗配對樣本t檢驗單樣本t檢驗前言在這篇文章中,我不會具體去推導檢驗統計量和相應拒絕域的得出,這對于大部分非統計學專業的人士來說是晦澀的,我只想通過一個案例告訴大部分初學者假設檢驗怎么在數據挖掘中使用。%ma…

中南民族大學計算機類有什么具體專業,中南民族大學計算機科學學院計算機科學與技術專業簡介...

計算機科學與技術專業計算機科學與技術專業1985年開始招收本科生。1989年開設計算機應用專業。1998年教育部進行專業調整,成立了計算機科學與技術專業。2012年,計算機科學與技術專業獲得校級品牌專業稱號。計算機科學與技術專業師資雄厚,結構…

Java實現字母的大小寫轉換

String result1 "JAVA";String result2 "springcloud";/*** toLowerCase()* 大寫轉小寫*/System.out.println(result1.toLowerCase());/*** 小寫轉大寫* toUpperCase()*/System.out.println(result2.toUpperCase()); 運行截圖如下:

iOS開發tableview二級聯動的細節實現中注意的細節總結

首先說網絡慢帶來的數據顯示問題 可以通過判斷請求參數是否一致來刷新tableview。 SJBCategaryModel * categaryModel self.categarys[CategarySelectRow]; NSMutableDictionary * params [NSMutableDictionary dictionary]; categaryModel.currentPage 1; params["a&q…

linux ctrlc 退出循環_linux按行讀取 (while read line與forloop)

在linux下一般用while read line與for循環按行讀取文件。這兩種方法有什么區別呢&#xff1f;現有如下test.txt文件&#xff1a;1while read linewhile read line; do echo $linedone < test.txt輸出結果與上圖一致。這里也可以寫為&#xff1a;cat test.txt | while read …