摘要:指向原型對象的構造函數二原型鏈什么是原型鏈原型鏈就是實例對象和原型對象之間的關系,他們使用來關聯。改變指向實現繼承創建類創建原型對象每天堅持鍛煉創建構造函數函數就是改變執行代碼片段中指向。
一. JS原型的簡單理解 1.1 prototype
prototype:是一個函數的屬性,每個函數中都會有一個prototype屬性,這個屬性是一個指針,指向一個對象。在JavaScript中原型是一個prototype對象,用于表示類型之間的關系。1.1.1 prototype定義
每個函數都有一個prototype屬性,這個屬性是指向一個對象的引用,這個對象稱為原型屬性。
function Person() {} var p = new Person();1.1.2 prototype 作用
原型對象包含實例共享的方法和屬性,這個函數用作構造函數時調用,使用new操作符調用的時候,新創建的對象會從原型對象上得到同樣的屬性和方法。
原型作用之一:數據共享,節省內存空間
原型作用之二:為了實現繼承
proto:是一個對象擁有的內置屬性,是js內部使用尋找原型鏈的屬性,通過該屬性可以允許使用實例對象直接訪問原型。
注意,prototype是函數的內置屬性,__proto__是對象的內置屬性
function Person() {} var p = new Person(); // 以前不能直接使用 p直接訪問對象原型 // 現在有了 __proto__ 后 // p.__proto__ 也可以直接訪問對象原型 // 那么 p.__proto__ === Person.prototype1.2.1. _proto_ 有什么用?
可以訪問原型
由于在開發中除非特殊要求, 不要使用實例去修改原型的成員. 因此屬性開發時使用較少
調試過程中非常方便, 可以輕易的訪問原型進行查看成員
1.3. constructorconstructor:屬性返回對創建此對象的函數的引用。(指向原型對象的構造函數)
二. 原型鏈 2.1 什么是原型鏈?原型鏈就是實例對象和原型對象之間的關系,他們使用__proto__來關聯。
圖解:
分析: a._proto_ ==Funciton構造函數的原型對象,其實原型對象也是一個實例化對象,既然是對象,那么他就是用Object來創建的, 既 var obj = new Object();所以Functionde的原型對象._proto_ = = Object構造函數的原型對象
2.2 原型對象是否可以改變看下面的圖文解讀:
function Person(name,age){ this.name = name; this.age = age; }; Person.prototype = { run:function(){ console.log("每天堅持鍛煉"); } }; var person1 = new Person("Tom",20); person1.run();// 輸出每天堅持鍛煉身體
很顯然,構造函數的原型對象是可以進行改變的,改變之后,當實例化對象時,它的原型對象就是構造函數新指向的對象。三. 繼承 3.1 什么是繼承?
繼承是一種關系,類(Class)與類之間的關系,JS中沒有類,但是可以通過構造函數模擬類,然后通過原型來實現繼承。繼承是為了數據共享,js中的繼承也是為了實現數據共享
eg:構建一個類是"人",他有姓名,性別,年齡等屬性和方法,再構建一個學生類,他可以繼承人的姓名,性別年齡等屬性,并且他還有屬于他自己的方法,比如:學習行為。看下面代碼:
//定義一個人的類別 function Person (name,age,sex) { this.name = name; this.age = age; this.sex = sex; } Student.prototype = new Person("Tom",20,"man"); //定義一個學生類別 function Student(){ this.s = function(){ console.log("學生的天職就是學習"); } } //實例化一個學生對象 var student = new Student(); student.s();// 學生的天職就是學習 console.log(student.name);// Tom console.log(student.age);// 20 console.log(student.sex);// man
分析: 實例化學生的對象繼承了 Student對象的 方法,并且繼承了 Person 對象的姓名,年齡,性別 屬性。這就是繼承。3.2 實現繼承的兩種方式 3.2.1 改變原型對象的指向實現繼承
看下面的圖文詳解
// 創建一個動物類別 function Animal (weight,color) { this.weight = weight; this.color = color; }; // 創建一個狗類 function Dog(){ this.bite = function (){ console.log("咬人"); }; }; Dog.prototype = new Animal("25kg","white"); //創建一個二哈(狗的品種)類 function Erha(){ this.sayHello = function(){ console.log("二哈是我們的好朋友,但是讓人討厭的是它會拆家!"); } } Erha.prototype = new Dog(); // 實例化一個對象 var dog = new Erha(); dog.bite();// 咬人 dog.sayHello();// 二哈是我們的好朋友,但是讓人討厭的是它會拆家! console.log(dog.weight);// 25kg console.log(dog.color);//white
分析:首先創建一個Animal構造函數,里面有兩個屬性,然后在創建一個Dog構造函數,并改變Dog構造函數的原型對象 既 Dog.prototype = new Animal("25kg","white"); 最后創建Erha對象,再次改變Erha的原型對象,
Erha.prototype = new Dog(); 實例化一個對象,這時。這個實例化的對象就擁有了Animal的屬性和方法,包括Dog的屬性和方法,這就實現了繼承,
缺陷: 如果實例化出來的對象,那么它的屬性初始化值都是一樣的。
3.2.2 改變 this 指向實現繼承// 創建Person類 function Person(name,age,sex){ this.name = name; this.age = age; this.sex = sex; }; // 創建原型對象 Person.prototype.run = function(){ console.log("每天堅持鍛煉"); } // 創建Studet 構造函數 function Student(name,age,sex,score){ // call函數就是改變執行代碼片段中this指向。 // this指的是當前函數 Person.call(this,name,age,sex); this.score = score; this.study = function(){ console.log("學生的天職就是學習"); } }; // 改變Student的原型對象,下面這句代碼很重要,如果沒有這句代碼會出現不能繼承父類原型對象的方法,這也是改變this指向繼承的缺陷,所以我們可以采用兩中模式共存的思想進行繼承。 Student.prototype = new Person(); var stu1 = new Student("Tom",19,"man",80); stu1.run();// 每天堅持鍛煉 console.log(stu1.name);// Tom console.log(stu1.age);// 19 console.log(stu1.sex);// man console.log(stu1.score);// 80
分析:其實這個很簡單,只要你明白this的指向就好明白了,this的指向見我的另一篇文章Js面向對象第六小結。先分析這個,首先創建類我就不說了,直接說這個this指向問題,這里小編用了一個call()方法,call函數能夠改變代碼片段的this指向,本例中this指向為當前函數,Person(this,name,age,sex)===this.name = name; this.age = age;this.sex = sex; 這下是不是明白了
補充: apply 函數,這個函數也可以實現改變this指向來完成繼承,見下面的代碼:
// 創建Person類 function Person(name,age,sex){ this.name = name; this.age = age; this.sex = sex; }; // 創建原型對象 Person.prototype.run = function(){ console.log("每天堅持鍛煉"); } // 創建Studet 構造函數 function Student(name,age,sex,score){ // call函數就是改變執行代碼片段中this指向。 // this指的是當前函數 Person.apply(this,[name,age,sex]); this.score = score; this.study = function(){ console.log("學生的天職就是學習"); } }; // 改變Student的原型對象 Student.prototype = new Person(); var stu1 = new Student("Tom",19,"man",80); stu1.run();// 每天堅持鍛煉 console.log(stu1.name);// Tom console.log(stu1.age);// 19 console.log(stu1.sex);// man console.log(stu1.score);// 80
這里只改變一句代碼: Person.apply(this,[name,age,sex]);
很明顯可以看出,apply和call的區別就是 參數問題,apply的第二個參數為數組,而call為數據
補充: bind函數
bind的作用是將函數復制一份并且改變函數中的this, 并且返回這個函數。
見下面的代碼分析:
function Person(name,age){ this.name = name; this.age = age; this.run = function(){ console.log(this.age); } } var p1 = new Person("Tom",15); var p2 = new Person("Jack",19); p1.run.bind(p2)();// 19
分析:使用bind函數時會復制一份函數,本例子是把 function(){console.log(this.age)} 復制了一份,并改變了此時的this 為p2.四. 總結
說實話,這節真的很難懂,我也是略懂一二而已,要想真正的明白,需要慢慢的沉淀,不知道正在學習前端的你針對這節內容有什么想法,可以留言告訴我,我們一起努力!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108114.html
摘要:原型鏈和對象的原型是對象實例和它的構造函數之間建立的鏈接,它的值是構造函數的。對象的原型根據上文提到的構造調用函數的時候會創建一個新對象,自動將的原型指向構造函數的對象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型鏈一直是比較難理解的內容,不少初學者甚至有一定經驗的老鳥都不一定能完全說清...
摘要:從實現角度分析原型鏈歡迎來我的博客閱讀從實現角度分析原型鏈網上介紹原型鏈的優質文章已經有很多了,比如說作為補充,就讓我們換個角度,從實現來分析一下吧本文假設你對原型鏈已經有所了解。 從實現角度分析js原型鏈 歡迎來我的博客閱讀:《從實現角度分析js原型鏈》 網上介紹原型鏈的優質文章已經有很多了,比如說: https://github.com/mqyqingfeng/Blog/issu...
摘要:相當于在用原型繼承編寫復雜代碼前理解原型繼承模型十分重要。同時,還要清楚代碼中原型鏈的長度,并在必要時結束原型鏈,以避免可能存在的性能問題。 js是一門動態語言,js沒有類的概念,ES6 新增了class 關鍵字,但只是語法糖,JavaScript 仍舊是基于原型。 至于繼承,js的繼承與java這種傳統的繼承不一樣.js是基于原型鏈的繼承. 在javascript里面,每個對象都有一...
摘要:圖片描述缺點是無法實現多繼承可以在構造函數中,為實例添加實例屬性。 對象的方法 Object.assign() 對象可以簡寫 ,如果 key 和 value 相等則可以簡寫 let name = xm; let age = 2; let obj = { name, age, fn(){ // 可以省略函數關鍵字和冒號: console.log(2...
摘要:構造函數,實例,原型三者的關系如下圖構造函數是構成整個原型鏈的關鍵,是他利用將原型傳給了后代。因此,通過操縱構造函數的,就能夠操縱原型鏈,從而對原型鏈進行自在的拼接。 要理解js的原型鏈主要就是理清楚以下三者的關系: 構造函數的protitype屬性 對象的__proto__屬性 對象的constructor屬性 在js中,函數作為一等公民,它是一個對象,可以擁有自己的屬性,可...
摘要:二構造函數我們先復習一下構造函數的知識上面的例子中和都是的實例。這兩個實例都有一個構造函數屬性,該屬性是一個指針指向。原型鏈其中是對象的實例。 一. 普通對象與函數對象 JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。下面舉例說明 var o1 = {}; var o2 =new Objec...
閱讀 2315·2021-11-24 10:33
閱讀 1385·2019-08-30 15:43
閱讀 3276·2019-08-29 17:24
閱讀 3481·2019-08-29 14:21
閱讀 2220·2019-08-29 13:59
閱讀 1735·2019-08-29 11:12
閱讀 2811·2019-08-28 18:00
閱讀 1848·2019-08-26 12:17