摘要:而和的存在就是為了建立這種子類與父類間的聯系。創建一個基本對象建立新對象與原型我把它理解為類之間的連接執行構造函數小結可以理解為類,也就是存儲一類事物的基本信息。原型原型鏈和繼承之間的關系。
原型 原型的背景
首先,你應該知道javascript是一門面向對象語言。
是對象,就具有繼承性。
繼承性,就是子類自動共享父類的數據結構和方法機制。
而prototype 和 __proto__ 的存在就是為了建立這種子類與父類間的聯系。
我們將prototype稱作原型,將通過__proto__來建立起來的對象與對象的關系稱作原型鏈。
下面,通過創建一個簡單對象,來探索原型和原型鏈到底是什么。
原型與原型鏈首先,創建一個最簡單的對象
function Foo(){} var o = new Foo();
ps:這是剛從java轉入JavaScript時,最令我費解的一段代碼,憑什么一個function就可以用來創建一個對象。下面就是new 關鍵字的分解動作。。。這個關鍵字究竟做了什么,能創建一個對象。。
這個創建的過程,可以分解成下面代碼
function Foo(){} // 創建一個基本對象 var o = new Object(); // 創建對象和父類原型之間的鏈接 o.__proto__ = Foo.prototype; // 執行構造函數 Foo.call(o);
為了更好的理解這段代碼,我們先理解這幾個概念
構造函數就是對象創建時,自動調用的方法
prototype,長這樣
{ constructor: f foo() __proto__: Object }
它是一個對象,存儲著一類事物的基本信息,所以可以將它稱作類。
__proto__,這個屬性用來建立對象和類之間的關系。
有了這些概念,我們來分析創建對象的過程中,究竟做了些什么.
創建一個對象,會做如下三件事。
創建一個基本對象 new Object()
建立新對象與原型(我把它理解為類)之間的連接
執行構造函數
小結:prototype可以理解為類,也就是存儲一類事物的基本信息。__proto__可以理解為一條線索,用來建立原型(類)和對象之間的關系。
原型、原型鏈和繼承之間的關系。繼承,需要滿足如下三個要求。
子類繼承父類的成員變量
子類繼承父類的方法
子類繼承父類的構造器,如果父類的構造函數帶有參數,那么子類中應該顯示調用
我們該如何實現繼承呢?
// 創建一個構造函數,我認為 a.prototype就是父類對象。 function a(x,y) { a.prototype.x = x; a.prototype.y = y } // 為父類對象添加一個method a.prototype.console = function() { console.log(this.x); console.log(this.y); } //創建子類構造函數 function b(x,y) { // 子類顯示的調用父類構造方法 a.call(this,x,y); } // 子類繼承父類的成員變量以及父類的方法 b.prototype = Object.create(a.prototype); = b.prototype.constructor = b; // 創建對象 var c = new b(1,2);
// 這里Object.create 是用來創建一個新的prototype,用來記錄新類的信息,并與父類建立聯系 Object.create = function() { //創建一個基本對象 var temp = new Object(); //與父類的的原型建立聯系 temp.__proto__ = proto; //返回新類的原型 return temp; }
小結:繼承關系的實現,做了如下兩件事情
子類顯示的調用父類的構造函數
子類通過原型來與父類建立聯系,從而能讓子類擁有父類的成員變量和方法。
原型就是類,原型鏈就是來建立子類和父類之間的聯系。
原型鏈的實際表現先創建一個類
function people() {} // 為父類對象添加一個method people.prototype.run = function() { console.log("I am running"); }
通過類來創建一個對象
var p = new people(); p.run(); // i am running
這里p對象長這樣
{ __proto__: Object }
很顯然,這個對象之中并沒有run方法。
但是它卻能調用run,因為它會通過__proto__(原型鏈)來尋找類中的方法。
經常有人這么問proto 和prototype有什么區別?我想看到這里,你應該很明白了。
prototype 一個存儲類信息的對象,只存在function中.(下圖中綠塊)
proto 單純是對象用來指向上級的一鏈接。(看下圖黃線)
那么又有人會問function中__proto__又是什么關系呢?
function 本身是對象,所以當然也有自己原型。function繼承于Function.(看下圖藍線)。
下面介紹一下原型繼承和類繼承的關系。
原型繼承和類繼An example that shows the difference between creating a JavaScript class and subclass in ES5 and ES6.
ES5
"use strict"; /** * Shape class. * * @constructor * @param {String} id - The id. * @param {Number} x - The x coordinate. * @param {Number} y - The y coordinate. */ function Shape(id, x, y) { this.id = id; this.setLocation(x, y); } /** * Set shape location. * * @param {Number} - The x coordinate. * @param {Number} - The y coordinate. */ Shape.prototype.setLocation = function(x, y) { this.x = x; this.y = y; }; /** * Get shape location. * * @return {Object} */ Shape.prototype.getLocation = function() { return { x: this.x, y: this.y }; }; /** * Get shape description. * * @return {String} */ Shape.prototype.toString = function() { return "Shape("" + this.id + "")"; }; /** * Circle class. * * @constructor * @param {String} id - The id. * @param {Number} x - The x coordinate. * @param {Number} y - The y coordinate. * @param {Number} radius - The radius. */ function Circle(id, x, y, radius) { Shape.call(this, id, x, y); this.radius = radius; } Circle.prototype = Object.create(Shape.prototype); Circle.prototype.constructor = Circle; /** * Get circle description. * * @return {String} */ Circle.prototype.toString = function() { return "Circle > " + Shape.prototype.toString.call(this); }; // test the classes var myCircle = new Circle("mycircleid", 100, 200, 50); // create new instance console.log(myCircle.toString()); // Circle > Shape("mycircleid") console.log(myCircle.getLocation()); // { x: 100, y: 200 }
ES6
"use strict"; /** * Shape class. * * @constructor * @param {String} id - The id. * @param {Number} x - The x coordinate. * @param {Number} y - The y coordinate. */ class Shape(id, x, y) { constructor(id, x, y) { // constructor syntactic sugar this.id = id; this.setLocation(x, y); } /** * Set shape location. * * @param {Number} - The x coordinate. * @param {Number} - The y coordinate. */ setLocation(x, y) { // prototype function this.x = x; this.y = y; } /** * Get shape location. * * @return {Object} */ getLocation() { return { x: this.x, y: this.y }; } /** * Get shape description. * * @return {String} */ toString() { return `Shape("${this.id}")`; } } /** * Circle class. * * @constructor * @param {String} id - The id. * @param {Number} x - The x coordinate. * @param {Number} y - The y coordinate. * @param {Number} radius - The radius. */ function Circle extends Shape { constructor(id, x, y, radius) { super(id, x, y); // call Shape"s constructor via super this.radius = radius; } /** * Get circle description. * * @return {String} */ toString() { // override Shape"s toString return `Circle > ${super.toString()}`; // call `super` instead of `this` to access parent } } // test the classes var myCircle = new Circle("mycircleid", 100, 200, 50); // create new instance console.log(myCircle.toString()); // Circle > Shape("mycircleid") console.log(myCircle.getLocation()); // { x: 100, y: 200 }
這段代碼,自己體會。。。。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89510.html
摘要:要搞清這三種關系指向之間的關系拗口,其實也就是要搞懂,構造函數由構造函數操作創造出的實例對象和構造函數的原型對象之間的關系。 寫在前面 這篇博客來源于,有天mentor突然傳給我了這張祖傳的圖片,并且發誓一定要給我講清楚,然鵝在他的一番激情講解之后,他自己也被繞懵了...于是后來我決定整理一下似乎還有點清晰的思路,記錄一下我對這張圖的理解。作為一個小白,對于js中這些比較復雜的概念的理...
摘要:繼承可以使得子類具有父類別的各種屬性和方法。繼承是類與類之間的關系。繼承的實質就是兩次的原型搜索,像是實例屬性而不是繼承,才是繼承。更多用法見繼承。 前言 面試中最常會問到的問題:什么是繼承?如何分別用 ES5 和 ES6 實現?想要學習繼承,必須先學好原型與原型鏈,如果此部分還不清楚,請先學習此部分再來閱讀本文,可參考我的文章JS之原型與原型鏈或瀏覽其他相關的學習網站。 定義 繼承...
之前也有和大家講過有關JS的對象創建和對象繼承,本篇文章主要為大家做個匯總和梳理。 JS中其實就是原型鏈繼承和構造函數繼承的毛病,還有就是工廠、構造、原型設計模式與JS繼承。 JS高級程序設計4:class繼承的重點,不只是簡簡單單的語法而已?! ο髣摻ā 〔浑y發現,每一篇都離不開工廠、構造、原型這3種設計模式中的至少其一! 那JS為什么非要用到這種3種設計模式了呢?? 我們先從對...
摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響年是向上的一年在新的城市穩定連續堅持健身三個月早睡早起游戲時間大大縮減,學會生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學習清單,發現僅有部分完成了。當然,這并不影響2018年是向上的一年:在新的城市穩定、...
摘要:請看對應版本干了什么可知,相當于以前在構造函數里的行為。這種寫法會與上文中寫法有何區別我們在環境下運行一下,看看這兩種構造函數的有何區別打印結果打印結果結合上文中關于原型的論述,仔細品味這兩者的差別,最好手動嘗試一下。 ES6 class 在ES6版本之前,JavaScript語言并沒有傳統面向對象語言的class寫法,ES6發布之后,Babel迅速跟進,廣大開發者也很快喜歡上ES6帶...
閱讀 1163·2021-11-15 18:14
閱讀 3627·2021-11-15 11:37
閱讀 754·2021-09-24 09:47
閱讀 2427·2021-09-04 16:48
閱讀 2182·2019-08-30 15:53
閱讀 2379·2019-08-30 15:53
閱讀 390·2019-08-30 11:20
閱讀 1232·2019-08-29 16:08