国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

探索 proto & prototype 與繼承之間的關(guān)系

dockerclub / 3579人閱讀

摘要:而和的存在就是為了建立這種子類與父類間的聯(lián)系。創(chuàng)建一個(gè)基本對(duì)象建立新對(duì)象與原型我把它理解為類之間的連接執(zhí)行構(gòu)造函數(shù)小結(jié)可以理解為類,也就是存儲(chǔ)一類事物的基本信息。原型原型鏈和繼承之間的關(guān)系。

原型 原型的背景

首先,你應(yīng)該知道javascript是一門面向?qū)ο笳Z言。

是對(duì)象,就具有繼承性。

繼承性,就是子類自動(dòng)共享父類的數(shù)據(jù)結(jié)構(gòu)和方法機(jī)制。

而prototype 和 __proto__ 的存在就是為了建立這種子類與父類間的聯(lián)系。

我們將prototype稱作原型,將通過__proto__來建立起來的對(duì)象與對(duì)象的關(guān)系稱作原型鏈。

下面,通過創(chuàng)建一個(gè)簡(jiǎn)單對(duì)象,來探索原型和原型鏈到底是什么。

原型與原型鏈

首先,創(chuàng)建一個(gè)最簡(jiǎn)單的對(duì)象

function Foo(){}
var o = new Foo();

ps:這是剛從java轉(zhuǎn)入JavaScript時(shí),最令我費(fèi)解的一段代碼,憑什么一個(gè)function就可以用來創(chuàng)建一個(gè)對(duì)象。下面就是new 關(guān)鍵字的分解動(dòng)作。。。這個(gè)關(guān)鍵字究竟做了什么,能創(chuàng)建一個(gè)對(duì)象。。

這個(gè)創(chuàng)建的過程,可以分解成下面代碼

  function Foo(){}
 // 創(chuàng)建一個(gè)基本對(duì)象
 var o = new Object();
 // 創(chuàng)建對(duì)象和父類原型之間的鏈接 
 o.__proto__ = Foo.prototype;
 // 執(zhí)行構(gòu)造函數(shù)
 Foo.call(o); 

為了更好的理解這段代碼,我們先理解這幾個(gè)概念

什么是構(gòu)造函數(shù)constructor

構(gòu)造函數(shù)就是對(duì)象創(chuàng)建時(shí),自動(dòng)調(diào)用的方法

prototype

prototype,長(zhǎng)這樣

{
    constructor: f foo()
    __proto__: Object
}

它是一個(gè)對(duì)象,存儲(chǔ)著一類事物的基本信息,所以可以將它稱作類。

__proto__

__proto__,這個(gè)屬性用來建立對(duì)象和類之間的關(guān)系。

有了這些概念,我們來分析創(chuàng)建對(duì)象的過程中,究竟做了些什么.
創(chuàng)建一個(gè)對(duì)象,會(huì)做如下三件事。

創(chuàng)建一個(gè)基本對(duì)象 new Object()

建立新對(duì)象與原型(我把它理解為類)之間的連接

執(zhí)行構(gòu)造函數(shù)

小結(jié):prototype可以理解為類,也就是存儲(chǔ)一類事物的基本信息。__proto__可以理解為一條線索,用來建立原型(類)和對(duì)象之間的關(guān)系。

原型、原型鏈和繼承之間的關(guān)系。

繼承,需要滿足如下三個(gè)要求。

子類繼承父類的成員變量

子類繼承父類的方法

子類繼承父類的構(gòu)造器,如果父類的構(gòu)造函數(shù)帶有參數(shù),那么子類中應(yīng)該顯示調(diào)用

我們?cè)撊绾螌?shí)現(xiàn)繼承呢?

// 創(chuàng)建一個(gè)構(gòu)造函數(shù),我認(rèn)為 a.prototype就是父類對(duì)象。
function a(x,y) {
    a.prototype.x = x;
    a.prototype.y = y
}
// 為父類對(duì)象添加一個(gè)method 
a.prototype.console = function() {
    console.log(this.x);
    console.log(this.y);
}
//創(chuàng)建子類構(gòu)造函數(shù)
function b(x,y) {
    // 子類顯示的調(diào)用父類構(gòu)造方法
    a.call(this,x,y);
}
// 子類繼承父類的成員變量以及父類的方法
b.prototype = Object.create(a.prototype); = b.prototype.constructor = b;
// 創(chuàng)建對(duì)象
var c = new b(1,2);
 // 這里Object.create 是用來創(chuàng)建一個(gè)新的prototype,用來記錄新類的信息,并與父類建立聯(lián)系
 Object.create = function() {
  //創(chuàng)建一個(gè)基本對(duì)象
  var temp = new Object();
  //與父類的的原型建立聯(lián)系
  temp.__proto__ = proto;
  //返回新類的原型
  return temp;
 }

小結(jié):繼承關(guān)系的實(shí)現(xiàn),做了如下兩件事情

子類顯示的調(diào)用父類的構(gòu)造函數(shù)

子類通過原型來與父類建立聯(lián)系,從而能讓子類擁有父類的成員變量和方法。

原型就是類,原型鏈就是來建立子類和父類之間的聯(lián)系。

原型鏈的實(shí)際表現(xiàn)

先創(chuàng)建一個(gè)類

function people() {}
// 為父類對(duì)象添加一個(gè)method
people.prototype.run = function() {
   console.log("I am running");
}

通過類來創(chuàng)建一個(gè)對(duì)象

var p = new people();
p.run();
// i am running

這里p對(duì)象長(zhǎng)這樣

{
__proto__: Object
}

很顯然,這個(gè)對(duì)象之中并沒有run方法。

但是它卻能調(diào)用run,因?yàn)樗鼤?huì)通過__proto__(原型鏈)來尋找類中的方法。

經(jīng)常有人這么問proto 和prototype有什么區(qū)別?

我想看到這里,你應(yīng)該很明白了。

prototype 一個(gè)存儲(chǔ)類信息的對(duì)象,只存在function中.(下圖中綠塊)

proto 單純是對(duì)象用來指向上級(jí)的一鏈接。(看下圖黃線)

那么又有人會(huì)問function中__proto__又是什么關(guān)系呢?

function 本身是對(duì)象,所以當(dāng)然也有自己原型。function繼承于Function.(看下圖藍(lán)線)。

下面介紹一下原型繼承和類繼承的關(guān)系。

原型繼承和類繼

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 }

這段代碼,自己體會(huì)。。。。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/89510.html

相關(guān)文章

  • 一張圖讓自己搞懂(mēng)原型&原型鏈

    摘要:要搞清這三種關(guān)系指向之間的關(guān)系拗口,其實(shí)也就是要搞懂,構(gòu)造函數(shù)由構(gòu)造函數(shù)操作創(chuàng)造出的實(shí)例對(duì)象和構(gòu)造函數(shù)的原型對(duì)象之間的關(guān)系。 寫在前面 這篇博客來源于,有天mentor突然傳給我了這張祖?zhèn)鞯膱D片,并且發(fā)誓一定要給我講清楚,然鵝在他的一番激情講解之后,他自己也被繞懵了...于是后來我決定整理一下似乎還有點(diǎn)清晰的思路,記錄一下我對(duì)這張圖的理解。作為一個(gè)小白,對(duì)于js中這些比較復(fù)雜的概念的理...

    CntChen 評(píng)論0 收藏0
  • JS之繼承(ES5 & ES6)

    摘要:繼承可以使得子類具有父類別的各種屬性和方法。繼承是類與類之間的關(guān)系。繼承的實(shí)質(zhì)就是兩次的原型搜索,像是實(shí)例屬性而不是繼承,才是繼承。更多用法見繼承。 前言 面試中最常會(huì)問到的問題:什么是繼承?如何分別用 ES5 和 ES6 實(shí)現(xiàn)?想要學(xué)習(xí)繼承,必須先學(xué)好原型與原型鏈,如果此部分還不清楚,請(qǐng)先學(xué)習(xí)此部分再來閱讀本文,可參考我的文章JS之原型與原型鏈或?yàn)g覽其他相關(guān)的學(xué)習(xí)網(wǎng)站。 定義 繼承...

    antyiwei 評(píng)論0 收藏0
  • 匯總有關(guān)JS對(duì)象創(chuàng)建繼承

      之前也有和大家講過有關(guān)JS的對(duì)象創(chuàng)建和對(duì)象繼承,本篇文章主要為大家做個(gè)匯總和梳理。  JS中其實(shí)就是原型鏈繼承和構(gòu)造函數(shù)繼承的毛病,還有就是工廠、構(gòu)造、原型設(shè)計(jì)模式與JS繼承。 JS高級(jí)程序設(shè)計(jì)4:class繼承的重點(diǎn),不只是簡(jiǎn)簡(jiǎn)單單的語法而已。  對(duì)象創(chuàng)建  不難發(fā)現(xiàn),每一篇都離不開工廠、構(gòu)造、原型這3種設(shè)計(jì)模式中的至少其一!  那JS為什么非要用到這種3種設(shè)計(jì)模式了呢??  我們先從對(duì)...

    3403771864 評(píng)論0 收藏0
  • 《你不知道javascript》筆記_對(duì)象&原型

    摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅(jiān)持健身三個(gè)月早睡早起游戲時(shí)間大大縮減,學(xué)會(huì)生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...

    seasonley 評(píng)論0 收藏0
  • ES6 class繼承super關(guān)鍵詞深入探索

    摘要:請(qǐng)看對(duì)應(yīng)版本干了什么可知,相當(dāng)于以前在構(gòu)造函數(shù)里的行為。這種寫法會(huì)與上文中寫法有何區(qū)別我們?cè)诃h(huán)境下運(yùn)行一下,看看這兩種構(gòu)造函數(shù)的有何區(qū)別打印結(jié)果打印結(jié)果結(jié)合上文中關(guān)于原型的論述,仔細(xì)品味這兩者的差別,最好手動(dòng)嘗試一下。 ES6 class 在ES6版本之前,JavaScript語言并沒有傳統(tǒng)面向?qū)ο笳Z言的class寫法,ES6發(fā)布之后,Babel迅速跟進(jìn),廣大開發(fā)者也很快喜歡上ES6帶...

    jubincn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<