成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

淺談javascript中的prototype

seanHai / 3017人閱讀

摘要:因此,請(qǐng)慎重重寫原型繼承說到就不得說繼承,我們通過給上添加屬性和方法,就能使該構(gòu)造函數(shù)所有的實(shí)例對(duì)象擁有屬性和方法。

本人博客:【www.xiabingbao.com】

在本文中,我們講解prototype的內(nèi)容主要由:什么是prototype,prototype與函數(shù)之間的關(guān)系,prototype與實(shí)例對(duì)象之間的關(guān)系,使用proto實(shí)現(xiàn)一個(gè)簡單的繼承。

1. prototype的簡要介紹

在javascript中,創(chuàng)建的每個(gè)函數(shù)天生都自帶著一個(gè)prototype屬性。這里我們要強(qiáng)調(diào)的是:這個(gè)prototype屬性是一個(gè)指針,指向一個(gè)對(duì)象,在這里,我們稱指向的這個(gè)看不到但確實(shí)存在的對(duì)象為原型對(duì)象。其實(shí)可以用下面一個(gè)簡單的例子來說明:

var proto = {
    name : "wenzi",
    age : 25
}
function Person(){

}
Person.prototype = proto;

這樣Person.protptype就指向到了proto,如果還有其他的引用(A)也指向到了proto,那么這個(gè)引用和Person.prototype就是相等的:A==Person.prototype;

prototype指向的這個(gè)對(duì)象是真實(shí)存在的,可能很多的同學(xué)對(duì)prototype屬性和原型對(duì)象有些混淆,我們?cè)谶@里把原型對(duì)象叫做大SB大SB與普通對(duì)象的一個(gè)不同之處就是,他也有一個(gè)天生的屬性:constructor,這個(gè)constructor重新指回到了函數(shù)。不過,既然大SB也是一個(gè)對(duì)象,那么它也是繼承于Object的,擁有Object所有的方法和屬性,比如toString()等。

大SB = {
    constructor : Person,
    say : function(){
        return "hello world";
    }
}

那么現(xiàn)在我們就能得到兩個(gè)引用關(guān)系:

大SB = Person.prototype; // 原型對(duì)象 = 函數(shù).prototype;
Person = 大SB.constructor(Person.prototype.constructor); // 函數(shù) = 原型對(duì)象.constructor(函數(shù).prototype.constructor)

從運(yùn)行的代碼中,可以驗(yàn)證我們的觀點(diǎn),Person.prototype的類型是object,Person.prototype.constructor重新指回到了Person。
其實(shí)在實(shí)例對(duì)象中,也存在著一個(gè)屬性指向到大SB中:

var John = new Person();
大SB = John.__proto__;

即 John.__proto__ 和 Person.prototype 指向的是同一個(gè)引用:John.__proto__==Person.prototype。

2. 對(duì)象實(shí)例和prototype中的屬性

在構(gòu)造函數(shù)能設(shè)置屬性和方法,在prototype中也能設(shè)置屬性和方法,那new出的對(duì)象使用的是哪個(gè)呢?我們來看一個(gè)例子:

function Person(){
    this.name = "wenzi";
}
Person.prototype.name = "bing";
Person.prototype.say = function(){
    return "hello world";
}
var John = new Person();
alert(John.name);  // "wenzi"
alert(John.say()); // "hello world"

從運(yùn)行的結(jié)果我們可以看到,John.name輸出的是構(gòu)造函數(shù)中的屬性值"wenzi",John.say()輸出的是"hello world"。這是因?yàn)?,?dāng)讀取某個(gè)對(duì)象的屬性值時(shí),會(huì)首先在實(shí)例對(duì)象中進(jìn)行搜索,若搜索到則直接進(jìn)行返回;若搜索不到則去原型對(duì)象中進(jìn)行尋找。因此在使用John調(diào)用say()方法時(shí)是正確的,不會(huì)報(bào)錯(cuò)。而且是進(jìn)行了兩次的搜索。

雖然say()是掛載在prototype上,John也同樣能直接進(jìn)行訪問。但是,我們不能直接對(duì)John.say進(jìn)行修改從而影響prototype的say()方法,如下:

John.say = function(){
    return "this has changed";
}
John.say(); // "this has changed"
var Tom = new Person();
Tom.say(); // "hello world"

從運(yùn)行John.say()的結(jié)果來看,say()方法確實(shí)發(fā)生了變化。但是,當(dāng)我們?cè)賜ew出一個(gè)新對(duì)象Tom時(shí),Tom.say()返回的還是"hello world",這是為什么呢?

因?yàn)?,?duì)John.say()進(jìn)行修改時(shí),不是修改了prototype上的say(),而是給John這個(gè)實(shí)例對(duì)象添加了一個(gè)say()方法,從而屏蔽了prototype上的say()方法,由上面的尋找順序我們可以知道,若實(shí)例對(duì)象存在這個(gè)方法就直接返回了,不再去原型對(duì)象上尋找。而new出的新對(duì)象Tom在調(diào)用say()方法時(shí),Tom自己是沒有say()方法的,只能去原型對(duì)象上尋找,因此返回的還是"hello world"。所以,對(duì)John.say進(jìn)行修改時(shí),不是修改了prototype上的say()方法,而是給John添加了實(shí)例方法,屏蔽掉了prototype上的方法而已。那如何才能修改prototype上的方法呢,好辦,直接在prototype上修改:

Person.prototype.say = function(){
    return "wenzi"s blog";
}

這樣就能修改prototype的say()方法了。

3. 重寫prototype

在上面的例子中,我們都是大部分給prototype添加屬性或方法,本來prototype指向的是大SB,若我們給prototype添加屬性或方法時(shí),就是給大SB添加屬性或方法:

Person.prototype.name = "wenzi"; 

大SB里其他的屬性和方法是不受影響的,constructor依然指回到Person。但是,若我們這樣寫:

Person.prototype = {
    name : "wenzi",
    say : function(){
        return "my name is name"
    }
}

就是對(duì)Person的prototype重寫了,讓prototype進(jìn)行了重新的指向,本來Person.prototype指向的是大SB,可是現(xiàn)在卻指向了CTM,而CTM里也沒有constructor屬性指回到Person,若是想重新指回到Person,還得手動(dòng)添加一個(gè)constructor屬性:

Person.prototype = {
    constructor : Person, // 重新指回到Person
    name : "wenzi",
    say : function(){
        return "my name is name"
    }
}

這樣就能手動(dòng)構(gòu)造出新的原型對(duì)象了,new出的實(shí)例對(duì)象也能使用這個(gè)prototype上的屬性和方法。

但是這里還存在一個(gè)問題,若之前已經(jīng)有new出的實(shí)例對(duì)象,然后再修改Person.prototype,之前的實(shí)例對(duì)象是無法使用新的原型對(duì)象(CTM)上的屬性和方法的,因?yàn)橹暗膶?shí)例對(duì)象的__proto__指向的依然是大SB。因此,請(qǐng)慎重重寫prototype

4. 原型繼承

說到prototype就不得說prototype繼承,我們通過給prototype上添加屬性和方法,就能使該構(gòu)造函數(shù)所有的實(shí)例對(duì)象擁有屬性和方法。我們先來看下面的代碼:

function Father(){
    this.name = "father";
    this.age = 43;
}
Father.prototype.job = "Doctor";
Father.prototype.getName = function(){
    return this.name;
}

function Son(){
    this.name = "son";
}
Son.prototype = new Father(); // Son的prototype指向Father的實(shí)例對(duì)象
var John = new Son();
for(var k in John){
    console.log(k+" : "+john[k]);
}
/*
    輸出結(jié)果:
    name : son
    age : 43
    job : Doctor
    getName : function (){
        return this.name;
    }
*/

從上面的例子中可以看到,Son的實(shí)例對(duì)象繼承了Father中所有的屬性和方法。當(dāng)然,若Son的對(duì)象實(shí)例中存在的,還依然保留。不過Son原型中的屬性和方法是會(huì)被徹底覆蓋的。我們來分析一下這是為什么?

Son的prototype指向的是Father的一個(gè)實(shí)例,我們把這拆成兩步:

var father = new Father();
Son.prototype = father;

在實(shí)例father中既有name,age屬性,也有Father.prototype中的屬性和方法,我們對(duì)father循環(huán)看一下:

for(var k in father){
    console.log(k, father[k]);
}
/*
    name father
    age 43
    job Doctor
    getName Father.getName()
*/

由于constructor是不可枚舉的類型,在for~in循環(huán)里是輸出不了constructor的,其實(shí)father是這樣的:

father = {
    constructor : Father,
    name : father
    age : 43
    job : Doctor
    getName : Father.getName()
}

因此Son的prototype指向的就是上面father的內(nèi)容。到此,Son的prototype中的constructor的指向也發(fā)生了改變,本來Son.prototype是指向到Son的,現(xiàn)在指向到了Father。即完全重寫了Son的prototype,重新指向了另一個(gè)引用。所以,我們就能知道為什么對(duì)象實(shí)例中的屬性能夠保存,而prototype中的會(huì)徹底被刪除了。

如果想給Son添加原型方法或?qū)傩?,那只能是?b>Son.prototype = new Father();之后進(jìn)行添加:

Son.prototype = new Father();
Son.prototype.getJob = function(){
    return this.job;
}

這樣就能添加上getJob方法了。

到這里,會(huì)有人問,如果Son.prototype = Father.prototype會(huì)怎么樣呢?我們剛才也說了Father.prototype指向的是大SB,而大SB也是一個(gè)實(shí)例對(duì)象,是Object的一個(gè)實(shí)例,這就相當(dāng)于:

Son.prototype == 大SB; // 指向了大SB

因此,如果是Son.prototype = Father.prototype的話,那么Son只能繼承到Father.prototype上的jobgetName(),其他的屬性是獲取不到的。

5. 總結(jié)

本文簡單的介紹了一下prototype,讓我們能對(duì)prototype有個(gè)淺顯的認(rèn)識(shí)。當(dāng)然,博主才疏學(xué)淺,文章里會(huì)有很多疏漏和不完善的地方,歡迎大家批評(píng)指正。

本人博客:【www.xiabingbao.com】

歡迎大家關(guān)注我的微信公眾號(hào):wenzichel

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

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

相關(guān)文章

  • 淺談JavaScript原型鏈

    摘要:在這其中我們就逃不開要討論繼承原型對(duì)象構(gòu)造函數(shù)實(shí)例了。想要獲得某一類型的構(gòu)造函數(shù)可以用來獲得,也可以對(duì)該屬性進(jìn)行賦值操作。三上面就提到一點(diǎn)是指構(gòu)造函數(shù)的原型對(duì)象,它是一個(gè)對(duì)象,它是構(gòu)造函數(shù)的屬性。 原型鏈這一個(gè)話題,需要和很多概念一起講,才能串成一個(gè)比較系統(tǒng)的知識(shí)點(diǎn)。在這其中我們就逃不開要討論繼承、原型對(duì)象、構(gòu)造函數(shù)、實(shí)例了。 一、構(gòu)造函數(shù) 構(gòu)造函數(shù)是一類特殊的函數(shù),它的作用是用來生成...

    xumenger 評(píng)論0 收藏0
  • 淺談JavaScript繼承

    摘要:組合方式實(shí)現(xiàn)繼承原型鏈構(gòu)造函數(shù)喵喵喵汪汪汪與的唯一區(qū)別是多了這一句組合方式實(shí)現(xiàn)了對(duì)構(gòu)造函數(shù)內(nèi)和原型上所有屬性和方法的繼承,并且的實(shí)例對(duì)象之間也不會(huì)相互干擾。 前言 關(guān)于JavaScript繼承相關(guān)的定義和方法網(wǎng)上已經(jīng)有很多解釋啦,本菜鳥就不抄抄寫寫惹人嫌了,本文主要探討三種基本的繼承方式并且給出優(yōu)化方案。 正文 借助構(gòu)造函數(shù)實(shí)現(xiàn)繼承 function Parent1() { ...

    Jingbin_ 評(píng)論0 收藏0
  • 淺談 JavaScript 原型鏈

    摘要:數(shù)組的構(gòu)造函數(shù)是原型鏈的指向與其他除以外的構(gòu)造函數(shù)相同,的也指向頂級(jí)原型對(duì)象,每一個(gè)數(shù)組都是的實(shí)例,都指向。實(shí)例對(duì)象查找構(gòu)造函數(shù)原型對(duì)象的方法一般會(huì)把對(duì)象共有的屬性和方法都放在構(gòu)造函數(shù)的原型對(duì)象上。 showImg(https://segmentfault.com/img/remote/1460000018998704?w=900&h=506); 閱讀原文 概述 在 JavaScr...

    explorer_ddf 評(píng)論0 收藏0
  • 淺談面向?qū)ο蟮?em>javascript幾個(gè)特性

    摘要:中的和是一門很靈活的語言,尤其是。即然是面向?qū)ο蟮木幊陶Z言,那也是不可或缺的。在中,永遠(yuǎn)指向的是他的調(diào)用者。定義是存在于實(shí)例化后對(duì)象的一個(gè)屬性,并且指向原對(duì)象的屬性。我們?cè)跀U(kuò)展的時(shí)候,同時(shí)父類也會(huì)有對(duì)應(yīng)的方法,這很顯然是一個(gè)很嚴(yán)重的問題。 javascript中的this和new javascript是一門很靈活的語言,尤其是function。他即可以以面向過程的方式來用,比如: f...

    JayChen 評(píng)論0 收藏0
  • 淺談 javascript 中的this綁定問題

    摘要:綁定使用方式進(jìn)行調(diào)用函數(shù)時(shí),會(huì)發(fā)生構(gòu)造函數(shù)的調(diào)用。先上圖,然后根據(jù)文字閱讀使用調(diào)用函數(shù)之后,該函數(shù)才作為構(gòu)造函數(shù)進(jìn)行調(diào)用,構(gòu)造一個(gè)全新的對(duì)象賦值給,而對(duì)象的指向了的對(duì)象,的對(duì)象有一個(gè)屬性指向的構(gòu)造函數(shù)這個(gè)就是的原型鏈,也是的特性。 javascript語言是在運(yùn)行時(shí)前即進(jìn)行編譯的,而this的綁定也是在運(yùn)行時(shí)進(jìn)行綁定的。也就是說,this實(shí)際上是在函數(shù)被調(diào)用時(shí)候發(fā)生綁定的,它指向什么完...

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

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

0條評(píng)論

閱讀需要支付1元查看
<