溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript原型實例分析

發(fā)布時間:2022-03-03 14:10:46 來源:億速云 閱讀:125 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“JavaScript原型實例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JavaScript原型實例分析”吧!

    先看三個對象

    一、構(gòu)造函數(shù)(對象):

    JS中聲明函數(shù)的三種方式

    1.function 函數(shù)名(){}聲明

    2.匿名函數(shù)聲明 var foo = function () {}

    3.構(gòu)造函數(shù)聲明 var foo = new Function("形參1","形參2","形參3")。任何函數(shù)都可以用

    new Function 來創(chuàng)建

            function fn1(name,age) {
                console.log(`我叫${name},我今年${age}歲`);
            }
            fn1('小航',19)
            // 定義函數(shù)的第二種方式
            const fn2 = function(name,sex) {
                console.log(`我叫${name},性別${sex}`);
            }
            fn2('小航','男')
            fn3('小航','男')
            // Function也是一個構(gòu)造函數(shù)
            // 上面的方式和下面的fn4聲明函數(shù)的方式是一致的
            const fn4 = new Function('name','age','console.log(`我叫${name},性別${sex}`)')
            // 當(dāng)然還有箭頭函數(shù) 只是寫法變了 和第一種類似
            const fn3 = (name, sex) => {
                console.log(`我叫${name},性別${sex}`);
            }

    當(dāng)我們用函數(shù)去創(chuàng)建對象時,如下Fun就是構(gòu)造函數(shù)。fn()是實例對象

            function Fun() {
            }
            var fn = new Fun()
            console.log(fn.__proto__ === Fun.prototype); // true

    并且知道:

    1. 任何函數(shù),上面的fn fn1 fn2 fn2都是Fun的實例,而Fun也是構(gòu)造函數(shù)Function的實例,F(xiàn)unction是JS內(nèi)置的對象。

    2. 看到上面一段代碼,F(xiàn)un.prototype指代/指向的是原型(對象,后面直接稱為原型)。

     我們接下來看第二個對象:

     二、實例對象

            function fn1(name,age) {
                console.log(`我叫${name},我今年${age}歲`);
            }
            const obj1 = {
                name: '小航',
                age: '19'
            }

    知道以下知識點:

    1. 只要用new關(guān)鍵字 + 構(gòu)造函數(shù)生成的對象,就是實例對象

    2. 即便沒有用new + 關(guān)鍵字,而是用比如字面量創(chuàng)建對象,或者是函數(shù)直接 function 函數(shù)名() {} 這樣聲明,生成的也是實例對象,如上面代碼 。

    3. 記住重要的知識點:所有的實例對象都有__proto__屬性,甚至可以去掉實例,改為所有的對象都有__proto__屬性。      

    4. 知道如下代碼中,fn 是構(gòu)造函數(shù)Fun的實例對象,并且Fun也是構(gòu)造函數(shù)Function的實例對象。

            function Fun() {
            }
            var fn = new Fun()

    得出的結(jié)論是:

    1. fn實例對象的__proto__屬性指向構(gòu)造函數(shù)Fun的屬性prototype【原型】

    2. 而Fun的實例對象的__proto__屬性也指向構(gòu)造函數(shù)的Function的prototype【原型】              備注:在這里,prototype既是Fun的屬性,而Fun.prototype也是最終的一個地方,目的地,這個目的地叫作原型對象。

            // 1. fn是Fun()構(gòu)造函數(shù)的實例 實例對象的__proto__屬性都會指向自身構(gòu)造函數(shù)的prototype屬性
            function Fun() {
            }
            var fn = new Fun()
            console.log(fn.__proto__ === Fun.prototype); // true
            // 2. Fun函數(shù)是Function構(gòu)造函數(shù)的實例 因此Fun的__proto__和構(gòu)造函數(shù)Function指向同一個地方
            console.log(Fun.__proto__ === Function.prototype); // true

    第一個console對應(yīng)下圖的序號1,第二個console對應(yīng)下圖的序號4

    JavaScript原型實例分析

    三、 原型對象:

    知道知識點:

    1. 所有的函數(shù)都有一個原型對象。比如函數(shù)Function,它有原型對象Function.prototype。也有說法叫Function.prototype 為 函數(shù)Function的伴生對象,意思是函數(shù)Function一創(chuàng)建,就有一個陪伴它一起創(chuàng)建的對象叫Function.prototype。而Function自己的身上,又有一個屬性叫作prototype,這個屬性指向了它的伴生對象。

    2. 函數(shù)的原型對象身上有一個屬性,叫作,constructor,它能夠指回構(gòu)造函數(shù)。就好像,構(gòu)造函數(shù)Function通過屬性prototype指向了原型對象Function.prototype,而原型對象Function.prototype通過自身的constructor屬性指回去。

     比如下面的,可以自行驗證。

            function fn() {
            }
            console.log(fn.prototype);
            console.log(fn.prototype.constructor === fn); // true

    3. 函數(shù)的原型對象身上還有一個屬性,叫作__proto__屬性。瀏覽器打印出來現(xiàn)在長這樣,

    [[Prototype]]: Object

    原型當(dāng)中的__proto__指向父類的原型對象prototype,比如下面的代碼

    下面的意思是函數(shù)Person的prototype,這是一個原型對象,它的__proto__屬性指向Object父類的prototype,F(xiàn)unction也是類似。為什么是這樣?

    因為既然Person.prototypeFunction.prototype都叫作原型對象,都是對象,那么本質(zhì)都是通過new Object創(chuàng)建的,都是構(gòu)造函數(shù)Object的實例,因此它們也是實例對象,身上也有__proto__屬性指向Object父類。

        function Person() {
        }
        console.log(Person.prototype.__proto__ === Object.prototype); // true
        console.log(Function.prototype.__proto__ === Object.prototype); // true

    對應(yīng)下圖的序號3

    JavaScript原型實例分析

    記?。?/strong>

    Object是各個對象的根

    再看三個屬性:

    一、prototype:

    1. 記住這個屬性是函數(shù)獨有的

    下面的代碼,fn有prototype,F(xiàn)un構(gòu)造函數(shù)有prototype,F(xiàn)unction下面沒寫出來,但是也有prototype。

    看代碼

            var fn55 = new Function('age', 'sex', 'console.log(`今年${age}性別${sex}`)')
            console.log(fn55.prototype);
            console.log(fn55.__proto__ === Function.prototype); // true

    注意:

    1. 上面的fn55是通過new Function創(chuàng)建的一個函數(shù),

    2. 函數(shù)有prototype 

    3. 同時fn55也是通過new + Function 創(chuàng)建的一個實例對象, 因此也有__proto__,指向Function構(gòu)造函數(shù)的prototype

    看下面代碼

            function Fun(name, age) {
                this.name = name;
                this.age = age
            }   
            var fnn = new Fun('小航', '123')
            console.log(fnn.prototype); // undefined

    注意上面代碼:

    1. 上面是通過new + Fun 創(chuàng)建了一個實例對象

    2. 這里是通過構(gòu)造函數(shù)Fun創(chuàng)建了一個對象fnn,而fnn并不是函數(shù),因此并沒有prototype原型對象

    二、__proto__

    1. 記得萬物都是對象 因此萬物都有__proto__

    2. 構(gòu)造函數(shù)的創(chuàng)建的實例對象,有__proto__,指向構(gòu)造函數(shù)的prototype

            function Person(name,age) {
                this.name = name
                this.age= age
            }
            Person.prototype.sayHello = function() {
                console.log(this.name);
            }
            const obj1 = {
                name: '小航',
                age: '19'
            }
            const obj2 = new Object()
            obj2.name = '焦邁奇'
            obj2.age = '19'
            console.log(obj1);
            console.log(obj2);
            console.log(Person.prototype);
            const person1 = new Person('小紅', 19)
            const person2 = new Person('小明', 20)
            console.log(person1.__proto__);
            console.log(person2.__proto__);
            console.log(Person.prototype === person1.__proto__);// true
            console.log(Person.prototype === person2.__proto__);// true
            console.log(Object.prototype === obj1.__proto__);   // true
            console.log(Object.prototype === obj2.__proto__);        // true

    3. 函數(shù)實例有__proto__,也指向構(gòu)造函數(shù)Function

            // 2. 創(chuàng)建函數(shù)的幾種方式
            // 定義函數(shù)的第一種方式
            function fn1(name,age) {
                console.log(`我叫${name},我今年${age}歲`);
            }
            fn1('小航',19)
            // 定義函數(shù)的第二種方式
            const fn2 = function(name,sex) {
                console.log(`我叫${name},性別${sex}`);
            }
            fn2('小航','男')
            // 或者箭頭函數(shù)
            const fn3 = (name, sex) => {
                console.log(`我叫${name},性別${sex}`);
            }
            fn3('小航','男')
            // 這三個函數(shù)的__proto__等于構(gòu)造函數(shù)Function的prototype
            // Function也是一個構(gòu)造函數(shù)
            // 上面的三種方式本質(zhì)和下面的fn4聲明函數(shù)的方式是一致的
            // 定義函數(shù)的第三種方式
            const fn4 = new Function('name','age','console.log(`我叫${name},性別${sex}`)')
            // console.log(Function.prototype === fn1.__proto__); // true
            // console.log(Function.prototype === fn2.__proto__); // true
            // console.log(Function.prototype === fn3.__proto__); // true
            // console.log(Function.prototype === fn4.__proto__); // true

    4. function Object和 function Function 都是構(gòu)造函數(shù)Function的實例,因此也有__proto__

            console.log(Object.__proto__ === Function.prototype); 
            // true
            console.log(Function.__proto__ === Function.prototype);
            // true

    5. 原型對象也是對象,因此也有__proto__

            function Person() {
            }
            console.log(Person.prototype.__proto__ === Object.prototype); // true
            console.log(Function.prototype.__proto__ === Object.prototype); // true

    三、constructor屬性

    每一個原型對象身上,才有constructor屬性

            function fn() {
            }
            console.log(fn.prototype);
            console.log(fn.prototype.constructor === fn); // true
            console.log(Function.prototype.constructor === Function); // true
            console.log(Object.prototype.constructor === Object);

    一些更加復(fù)雜的情況

    console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__=== null); // null

    1. obj.__proto__指向Object.prototype

    2. Object.prototype.constructor就是指向Object本身

    備注:Object也是構(gòu)造函數(shù)也是Function的實例對象 因此下面Object也有__proto__

    3. Object.__proto__指向Function.prototype

    4. Function.prototype.__proto__指向什么?這個就是[原型對象也是對象]原型對象的__proto__指向什么?指向的是父類的prototype也就是Object.prototype

    5. Object.prototype指向什么,就是原型鏈的終點null 可以下去自行驗證

    原型鏈

    原型鏈就是__proto__的終點

    感謝各位的閱讀,以上就是“JavaScript原型實例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對JavaScript原型實例分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI