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

資訊專欄INFORMATION COLUMN

Javascript函數(shù)執(zhí)行、new機(jī)制以及繼承

sshe / 1252人閱讀

摘要:函數(shù)執(zhí)行一個(gè)函數(shù),被執(zhí)行有三種途徑或機(jī)制以及繼承中定義了一種對象,稱之為對象,其內(nèi)部實(shí)現(xiàn)包括以下說明該對象可以被執(zhí)行,具有屬性說明該對象可以接受操作,具有構(gòu)造器屬性指向?qū)ο蟮脑玩湣?/p>

JS函數(shù)執(zhí)行

一個(gè)JavaScript函數(shù)fn,被執(zhí)行有三種途徑:

fn()

new fn()

fn.call()或fn.apply()

new機(jī)制以及繼承

JavaScript中定義了一種對象,稱之為ECMAScript對象,其內(nèi)部實(shí)現(xiàn)包括以下:

__call__: 說明該對象可以被執(zhí)行,具有function屬性

__construct__: 說明該對象可以接受new操作,具有構(gòu)造器屬性

__prototype__: 指向?qū)ο蟮脑玩湣τ诙x的函數(shù),會指向Function.prototype

注意:__prototype__是原型鏈,對所有對象都有的。prototype是原型,是函數(shù)才有的,就是一個(gè)普通的對象而已,目的是為了接受new后給生成的對象提供原型鏈的。

執(zhí)行fn就是調(diào)用__call__

執(zhí)行new fn()會進(jìn)行以下簡化過程:

新建一個(gè)對象,記作o

把o.__prototype__指向fn.prototype(如果fn.prototype不是一個(gè)Object,則指向Object.prototype)

執(zhí)行fn,并用o作為this(即內(nèi)部實(shí)現(xiàn)的fn.call(this))。如果fn返回是一個(gè)object,則返回object, 否則把o返回

fn.call(obj)或者fn.apply(obj)就是將obj作為this,執(zhí)行fn。本質(zhì)是調(diào)用__call__,只是傳入了obj作為this.

    //定義一個(gè)函數(shù),正常函數(shù)會具有__call__, __construct__
    //同時(shí)Parent.__proto__指向Function.prototype
    function Parent() {
        this.sayAge = function() {
            console.log("age is: " + this.age);
        }
    }
    //原型上添加一個(gè)方法
    Parent.prototype.sayParent = function(){
        console.log("this is Parent Method");
    }
    
    //定義另一個(gè)函數(shù)
    function Child(firstname){
    
        //這里就是調(diào)用Parent的__call__, 并且傳入this
        //而這里的this,是Child接受new時(shí)候生成的對象
        //因此,這一步會給生成的Child生成的實(shí)例添加一個(gè)sayAge屬性
        Parent.call(this);
        
        this.fname = firstname;
        this.age = 40;
        this.saySomething = function() {
            console.log(this.fname);
            this.sayAge();
        }
    }
    
    //這一步就是new的調(diào)用,按原理分步來看
    //1. 新建了個(gè)對象,記作o
    //2. o.__prototype__ = Parent.prototype, 因此o.sayParent會訪問到o.__prototype__.sayParent(原型鏈查找機(jī)制)
    //3. Parent.call(o), 因此o也會有個(gè)sayAge屬性(o.sayAge)
    //4. Child.prototype = o, 因此 Child.prototype 通過o.__prototype__ 這個(gè)原型鏈具有了o.sayParent屬性,同時(shí)通過o.sayAge 具有了sayAge屬性(也就是說Child.prototype上具有sayAge屬性,但沒有sayParent屬性,但是通過原型鏈,也可以訪問到sayParent屬性)
    Child.prototype = new Parent();
    
    //這也是一步new調(diào)用
    //1. 新建對象,記作s
    //2. s.__prototype__ = Child.prototype, 此時(shí)s會具有sayAge屬性以及sayParent這個(gè)原型鏈上的屬性
    //3. Child.call(s), 執(zhí)行后, 增加了fname, age, saySomething屬性, 同時(shí)由于跑了Parent.call(s), s還具有sayAge屬性, 這個(gè)屬性是s身上的, 上面那個(gè)sayAge是Child.prototype上的, 即s.__prototype__上的。
    //4. child = s
    var child = new Child("張")
    
    //child本身屬性就有,執(zhí)行
    child.saySomething();
    
    //child本身屬性沒有, 去原型鏈上看, child.__prototype__ = s.__prototype__ = Child.prototype = o, 這里沒找到sayParent, 繼續(xù)往上找, o.__prototype__ = Parent.prototype, 這里找到了, 執(zhí)行(第二層原型鏈找到)
    child.sayParent();

原理來看寫得有些繁瑣,本身其實(shí)是比較簡單的東西。
重點(diǎn)是new的過程,原型prototype和原型鏈__prototype__
也正是new的原理,導(dǎo)致了原型鏈的繼承,本質(zhì)是生成的對象的__prototype__指向了函數(shù)的原型prototype

更復(fù)雜的調(diào)用繼承之類的,都可以通過這個(gè)原理來理解。說白了,原型鏈繼承就是復(fù)用了prototype而已。

本例來看,Child中的Parent.call(this)看似沒有必要,但本質(zhì)上是有區(qū)別的。如果去掉這一句,則Child的實(shí)例本身將沒有sayAge屬性,而Child.prototype具有sayAge屬性,因此實(shí)例的__prototype__具有sayAge屬性,因此還可以執(zhí)行。

但目的是為了繼承,因此屬性是需要對象上本身持有,而非是通過原型鏈上來訪問,所以加上這一句是原理上的嚴(yán)謹(jǐn)要求。可以通過下面的例子來檢驗(yàn):

    function Parent() {
        this.sayAge = function() {
            console.log("age is: " + this.age);
        }
    }
    Parent.prototype.sayParent = function(){
        console.log("this is Parent Method");
    }
    
    function Child(firstname){
        Parent.call(this); 
        this.fname = firstname;
        this.age = 40;
        this.saySomething = function() {
            console.log(this.fname);
            this.sayAge();
        }
    }
    
    Child.prototype = new Parent();
    
    var child = new Child("張")
    
    child.saySomething();
    child.sayParent();
    
    console.log(child.hasOwnProperty("sayAge")); // true
    child.sayAge(); //能調(diào)用,此時(shí)調(diào)用的是自身的屬性
    delete child.sayAge; // delete只能刪除自身的屬性,不能刪除原型鏈屬性
    console.log(child.hasOwnProperty("sayAge")); // false,自身沒有這個(gè)屬性了
    child.sayAge(); //還能調(diào)用,此時(shí)調(diào)用的是原型鏈上的方法

如果刪掉Parent.call(this), 上面兩句child.hasOwnProperty("sayAge"), 都將返回false

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88876.html

相關(guān)文章

  • 這一次,我們換種姿勢學(xué)習(xí) javascript

    摘要:操作符或調(diào)用函數(shù)時(shí)傳入?yún)?shù)的操作都會導(dǎo)致關(guān)聯(lián)作用域的賦值操作。此外可以使用和來設(shè)置對象及其屬性的不可變性級別。忽視這一點(diǎn)會導(dǎo)致許多問題。使用調(diào)用函數(shù)時(shí)會把新對象的屬性關(guān)聯(lián)到其他對象。 前言 《你不知道的 javascript》是一個(gè)前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語言內(nèi)部,弄清楚JavaScript每一個(gè)零部件的用途。本書介紹了該系列的兩個(gè)主題:...

    zone 評論0 收藏0
  • JavasScript重難點(diǎn)知識

    摘要:忍者級別的函數(shù)操作對于什么是匿名函數(shù),這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數(shù)是一個(gè)很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個(gè)供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果...

    forsigner 評論0 收藏0
  • JavaScript 五十問——從源碼分析 ES6 Class 的實(shí)現(xiàn)機(jī)制

    摘要:防止類的構(gòu)造函數(shù)以普通函數(shù)的方式調(diào)用。這個(gè)函數(shù)的主要作用是通過給類添加方法,其中將靜態(tài)方法添加到構(gòu)造函數(shù)上,將非靜態(tài)的方法添加到構(gòu)造函數(shù)的原型對象上。 Class是ES6中新加入的繼承機(jī)制,實(shí)際是Javascript關(guān)于原型繼承機(jī)制的語法糖,本質(zhì)上是對原型繼承的封裝。本文將會討論:1、ES6 class的實(shí)現(xiàn)細(xì)2、相關(guān)Object API盤點(diǎn)3、Javascript中的繼承實(shí)現(xiàn)方案盤點(diǎn)...

    LeexMuller 評論0 收藏0
  • 前端_JavaScript_面向?qū)ο缶幊?/b>

    摘要:面向?qū)ο缶幊虒ο蟮脑椒ǚ殖蓛深愖陨淼姆椒o態(tài)方法和的實(shí)例方法。的靜態(tài)方法方法與,參數(shù)是對象,返回一個(gè)數(shù)組,數(shù)組的值是改對象自身的所有屬性名區(qū)別在于返回可枚舉的屬性,返回不可枚舉的屬性值。 面向?qū)ο缶幊?Objects對象的原生方法分成兩類:Object自身的方法(靜態(tài)方法)和Object的實(shí)例方法。注意Object是JavaScript的原生對象,所有的其他對象都是繼承自O(shè)bjec...

    Blackjun 評論0 收藏0
  • JavaScript面向?qū)ο蟮某绦蛟O(shè)計(jì)

    摘要:目錄導(dǎo)語理解對象和面向?qū)ο蟮某绦蛟O(shè)計(jì)創(chuàng)建對象的方式的繼承機(jī)制原型對象原型鏈與原型對象相關(guān)的方法小結(jié)導(dǎo)語前面的系列文章,基本把的核心知識點(diǎn)的基本語法標(biāo)準(zhǔn)庫等章節(jié)講解完本章開始進(jìn)入核心知識點(diǎn)的高級部分面向?qū)ο蟮某绦蛟O(shè)計(jì),這一部分的內(nèi)容將會對對象 目錄 導(dǎo)語 1.理解對象和面向?qū)ο蟮某绦蛟O(shè)計(jì) 2.創(chuàng)建對象的方式 3.JavaScript的繼承機(jī)制 3.1 原型對象 3.2 原型鏈 3.3 與...

    gitmilk 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<