溫馨提示×

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

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

es6構(gòu)造函數(shù)是不是只能有一個(gè)

發(fā)布時(shí)間:2022-10-18 15:39:50 來源:億速云 閱讀:115 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“es6構(gòu)造函數(shù)是不是只能有一個(gè)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“es6構(gòu)造函數(shù)是不是只能有一個(gè)”吧!

對(duì),每個(gè)類只能有一個(gè)構(gòu)造函數(shù),如果包含多個(gè)構(gòu)造函數(shù),那么會(huì)拋出異常。構(gòu)造函數(shù)是一種特殊的函數(shù),主要用來初始化對(duì)象,即為對(duì)象成員變量賦初始值;使用構(gòu)造函數(shù)時(shí)要注意兩點(diǎn):1、構(gòu)造函數(shù)用于創(chuàng)建某一類對(duì)象,其首字母要大寫;2、構(gòu)造函數(shù)要和new一起使用才有意義。

本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。

在典型的 OOP 的語言中(如 Java),都存在類的概念,類就是對(duì)象的模板,對(duì)象就是類的實(shí)例,但在 ES6之前, JS 中并沒用引入類的概念。

在 ES6之前 ,對(duì)象不是基于類創(chuàng)建的,而是用一種稱為構(gòu)建函數(shù)的特殊函數(shù)來定義對(duì)象和它們的特征。

創(chuàng)建對(duì)象可以通過以下三種方式:

  • 對(duì)象字面量

  • new Object()

  • 自定義構(gòu)造函數(shù)

// 1、利用 new Object() 創(chuàng)建對(duì)象
var obj1 = new Object();

// 2、利用對(duì)象字面量創(chuàng)建對(duì)象
var obj2 = {};

// 利用構(gòu)造函數(shù)創(chuàng)建對(duì)象
function Star(name,age) {
    this.name=name;
    this.age=age;
    this.sing=function(){
        console.log('唱歌');
    }
}

var ldh=new Star('劉德華',23);
console.log(ldh);
ldh.sing();
// Star { name: '劉德華', age: 23, sing: [Function (anonymous)] }
//唱歌

構(gòu)造函數(shù)

構(gòu)造函數(shù)是一種特殊的函數(shù),主要用來初始化對(duì)象,即為對(duì)象成員變量賦初始值,它總與 new 一起使用。我們可以把對(duì)象中一些公共的屬性和方法抽取出來,然后封裝到這個(gè)函數(shù)里面。

在 JS 中,使用構(gòu)造函數(shù)時(shí)要注意以下兩點(diǎn):

  • (1)構(gòu)造函數(shù)用于創(chuàng)建某一類對(duì)象,其首字母要大寫

  • (2)構(gòu)造函數(shù)要和 new 一起使用才有意義

每個(gè)類只能有一個(gè)構(gòu)造函數(shù),如果包含多個(gè)構(gòu)造函數(shù),那么會(huì)拋出異常

// 類的聲明
class Person {
 // 類的構(gòu)造方法 注:一個(gè)類只能有一個(gè)構(gòu)造函數(shù), 如果沒有定義那就自動(dòng)用默認(rèn)的
 // 通過new關(guān)鍵字操作類的時(shí)候,會(huì)調(diào)用constructor函數(shù),并執(zhí)行如下操作
 // 1、在內(nèi)存中創(chuàng)建一個(gè)對(duì)象 moni = {}
 // 2、 將類的原型prototype賦值給創(chuàng)建出來的對(duì)象 moni.__proto__ = Person.prototype
 // 3、將對(duì)象賦值給函數(shù)的this:new綁定 this = moni
 // 4、執(zhí)行函數(shù)中的代碼
 // 5、自動(dòng)返回創(chuàng)建出來的對(duì)象
 constructor() {
 }
}
 
 
let p1 = new Person()
 
let P2 = new Person('kobe', 30)

new 在執(zhí)行時(shí)會(huì)做四件事情:

(1)在內(nèi)存中創(chuàng)建一個(gè)新的空對(duì)象。

(2)讓 this 指向這個(gè)新的對(duì)象。

(3)執(zhí)行構(gòu)造函數(shù)里面的代碼,給這個(gè)新對(duì)象添加屬性和方法。

(4)返回這個(gè)新對(duì)象(所以構(gòu)造函數(shù)里面不需要 return )。

JavaScript 的構(gòu)造函數(shù)中可以添加一些成員,可以在構(gòu)造函數(shù)本身上添加,也可以在構(gòu)造函數(shù)內(nèi)部的 this 上添加。通過這兩種方式添加的成員,就分別稱為靜態(tài)成員和實(shí)例成員。

  • 靜態(tài)成員:在構(gòu)造函數(shù)本上添加的成員稱為靜態(tài)成員,只能由構(gòu)造函數(shù)本身來訪問

  • 實(shí)例成員:在構(gòu)造函數(shù)內(nèi)部創(chuàng)建的對(duì)象成員稱為實(shí)例成員,只能由實(shí)例化的對(duì)象來訪問

舉個(gè)栗子:

// 構(gòu)造函數(shù)中的屬性和方法稱為成員
function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    this.sing = function() {
        console.log('我會(huì)唱歌');

    }
}
var ldh = new Star('劉德華', 18);

// 1、實(shí)例成員就是構(gòu)造函數(shù)內(nèi)部通過this添加的成員
// uname、age、sing就是實(shí)例成員
// 實(shí)例成員只能通過實(shí)例化的對(duì)象來訪問
console.log(ldh.uname); //劉德華
ldh.sing();  //我會(huì)唱歌
// 不可以通過構(gòu)造函數(shù)來訪問實(shí)例成員
console.log(Star.uname); //undefined

Star.sex='男'
// 2、靜態(tài)成員 在構(gòu)造函數(shù)本身上添加的成員 sex 就是靜態(tài)成員
// 靜態(tài)成員只能通過構(gòu)造函數(shù)來訪問
console.log(Star.sex); //男
// 靜態(tài)成員不能通過對(duì)象來訪問
console.log(ldh.sex);  //undefined

構(gòu)造函數(shù)的問題

構(gòu)造函數(shù)方法很好用,但是存在浪費(fèi)內(nèi)存的問題。

es6構(gòu)造函數(shù)是不是只能有一個(gè)

我們希望所有的對(duì)象使用同一個(gè)函數(shù),這樣就比較節(jié)省內(nèi)存,那么我們要怎樣做呢?

構(gòu)造函數(shù)原型 prototype

構(gòu)造函數(shù)通過原型分配的函數(shù)是所有對(duì)象所共享的。

JavaScript 規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè) prototype 屬性,指向另一個(gè)對(duì)象。注意這個(gè) prototype 就是一個(gè)對(duì)象,這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)所擁有。

我們可以把那些不變的方法,直接定義在 prototype 對(duì)象上,這樣所有對(duì)象的實(shí)例就可以共享這些方法。

打印對(duì)象的屬性,查看prototype

 function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    this.sing = function() {
        console.log('我會(huì)唱歌');
    }
}
        console.dir(Star);

輸出結(jié)果:

es6構(gòu)造函數(shù)是不是只能有一個(gè)

  • 原型是什么 ?

一個(gè)對(duì)象,我們也稱為 prototype 為原型對(duì)象。

  • 原型的作用是什么 ?

共享方法。

舉個(gè)栗子:

function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    // this.sing=function() {
    //     console.log('我會(huì)唱歌');
    // }
}
     Star.prototype.sing=function() {
         console.log('我會(huì)唱歌');
     }
    var ldh= new Star('劉德華',18);
    var zxy= new Star('張學(xué)友',19);
    console.log(ldh.sing===zxy.sing); //采用this添加方法時(shí)輸出 false 采用prototype添加方法時(shí)輸出 true
    ldh.sing();
    zxy.sing();

對(duì)象原型__proto__

對(duì)象都會(huì)有一個(gè)屬性__proto__指向構(gòu)造函數(shù)的 prototype 原型對(duì)象,之所以我們對(duì)象可以使用構(gòu)造函數(shù) prototype 原型對(duì)象的屬性和方法,就是因?yàn)閷?duì)象有

__proto__原型的存在。

__proto__對(duì)象原型和原型對(duì)象 prototype 是等價(jià)的

__proto__對(duì)象原型的意義就在于為對(duì)象的查找機(jī)制提供一個(gè)方向,或者說一條路線,但是它是一個(gè)非標(biāo)準(zhǔn)屬性,因此實(shí)際開發(fā)中,不可以使用這個(gè)屬性,它只是內(nèi)部指向原型對(duì)象 prototype

es6構(gòu)造函數(shù)是不是只能有一個(gè)

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype.sing=function(){
            console.log('我會(huì)唱歌');
        }
        var ldh = new Star('劉德華', 18);
        var zxy = new Star('張學(xué)友', 19);
        console.log(ldh); 
        //對(duì)象身上系統(tǒng)自己添加一個(gè)__proto__ 指向構(gòu)造函數(shù)的原型對(duì)象 prototype
        console.log(ldh.__proto__===Star.prototype); //true
        // 方法的查找規(guī)則(以sing方法為例):
        // 首先看 實(shí)例對(duì)象身上是否有 sing 方法,如果有就執(zhí)行這個(gè)對(duì)象的sing
        // 如果沒有sing 方法,因?yàn)橛衉_proto__的存在,就去 構(gòu)造函數(shù)原型對(duì)象prototype身上找sing 方法

es6構(gòu)造函數(shù)是不是只能有一個(gè)

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

對(duì)象原型__proto__和構(gòu)造函數(shù)(prototype)原型對(duì)象里面都有一個(gè)屬性 constructor 屬性 ,constructor 我們稱為構(gòu)造函數(shù),因?yàn)樗富貥?gòu)造函數(shù)本身。

es6構(gòu)造函數(shù)是不是只能有一個(gè)

constructor 主要用于記錄該對(duì)象引用于哪個(gè)構(gòu)造函數(shù),它可以讓原型對(duì)象重新指向原來的構(gòu)造函數(shù)。

一般情況下,對(duì)象的方法都在構(gòu)造函數(shù)的原型對(duì)象中設(shè)置。如果有多個(gè)對(duì)象的方法,我們可以給原型對(duì)象采取對(duì)象形式賦值,但是這樣就會(huì)覆蓋構(gòu)造函數(shù)原型對(duì)象原來的內(nèi)容,這樣修改后的原型對(duì)象 constructor  就不再指向當(dāng)前構(gòu)造函數(shù)了。此時(shí),我們可以在修改后的原型對(duì)象中,添加一個(gè) constructor 指向原來的構(gòu)造函數(shù)。

   function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype = {
            // 如果我們修改了原來的原型對(duì)象,給原型對(duì)象賦值的是一個(gè)對(duì)象,則必須手動(dòng)的利用constructor指回原來的構(gòu)造函數(shù)
            constructor: Star,
            sing: function() {
                console.log('我會(huì)唱歌');
            },
            movie: function() {
                console.log('我會(huì)演電影');
            }
        }
        var ldh = new Star('劉德華', 18);
        console.log(Star.prototype.constructor);
        console.log(ldh.__proto__.constructor);

es6構(gòu)造函數(shù)是不是只能有一個(gè)

給原型對(duì)象采取對(duì)象形式賦值,會(huì)覆蓋構(gòu)造函數(shù)原型對(duì)象原來的內(nèi)容,就不會(huì)有constructor指向當(dāng)前構(gòu)造函數(shù)

        Star.prototype = {
            sing: function() {
                console.log('我會(huì)唱歌');
            },
            movie: function() {
                console.log('我會(huì)演電影');
            }
        }
      console.dir(Star);

es6構(gòu)造函數(shù)是不是只能有一個(gè)

解決辦法:手動(dòng)的利用constructor指回原來的構(gòu)造函數(shù)

        Star.prototype = {
            // 如果我們修改了原來的原型對(duì)象,給原型對(duì)象賦值的是一個(gè)對(duì)象,則必須手動(dòng)的利用constructor指回原來的構(gòu)造函數(shù)
            constructor: Star,
            sing: function() {
                console.log('我會(huì)唱歌');
            },
            movie: function() {
                console.log('我會(huì)演電影');
            }
        }

構(gòu)造函數(shù)、實(shí)例、原型對(duì)象三者之間的關(guān)系

es6構(gòu)造函數(shù)是不是只能有一個(gè)

感謝各位的閱讀,以上就是“es6構(gòu)造函數(shù)是不是只能有一個(gè)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)es6構(gòu)造函數(shù)是不是只能有一個(gè)這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

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

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

es6
AI