首頁 > web前端 > 前端問答 > es6建構函式只能有一個嗎

es6建構函式只能有一個嗎

青灯夜游
發布: 2022-10-18 15:04:53
原創
2186 人瀏覽過

對,每個類別只能有一個建構函數,如果包含多個建構函數,那麼就會拋出異常。建構函數是一種特殊的函數,主要用來初始化對象,即為對象成員變數賦初始值;使用建構子時要注意兩點:1、建構子用來建立某一類對象,其首字母要大寫;2、建構函數要和new一起使用才有意義。

es6建構函式只能有一個嗎

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

在典型的OOP 的語言中(如Java),都存在類別的概念,類別就是物件的模板,物件就是類別的實例,但在ES6之前, JS 中並沒用引入類別的概念。

在 ES6之前 ,物件不是基於類別創建的,而是用一種稱為建構函數的特殊函數來定義物件和它們的特徵。

建立物件可以透過以下三種方式:

  • 物件字面量

  • new Object()

  • 自訂建構子

// 1、利用 new Object() 创建对象
var obj1 = new Object();

// 2、利用对象字面量创建对象
var obj2 = {};

// 利用构造函数创建对象
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)] }
//唱歌
登入後複製

#建構子

##建構子是一種特殊的函數,主要用來初始化對象,即為對象成員變數賦初始值,它總是與new 一起使用。我們可以把物件中一些公共的屬性和方法抽取出來,然後封裝到這個函數裡面。

在JS 中,使用建構子時要注意以下兩點:

  • (1)建構子用來建立某一類別對象,其首字母要大寫

  • (2)建構子要和new 一起使用才有意義

每個類別只能有一個建構函數,如果包含多個建構函數,那麼會拋出異常

// 类的声明
class Person {
 // 类的构造方法 注:一个类只能有一个构造函数, 如果没有定义那就自动用默认的
 // 通过new关键字操作类的时候,会调用constructor函数,并执行如下操作
 // 1、在内存中创建一个对象 moni = {}
 // 2、 将类的原型prototype赋值给创建出来的对象 moni.__proto__ = Person.prototype
 // 3、将对象赋值给函数的this:new绑定 this = moni
 // 4、执行函数中的代码
 // 5、自动返回创建出来的对象
 constructor() {
 }
}
 
 
let p1 = new Person()
 
let P2 = new Person('kobe', 30)
登入後複製

new 在執行時會做四件事:

(1)在記憶體中建立一個新的空對象。

(2)讓 this 指向這個新的物件。

(3)執行建構子裡面的程式碼,為這個新物件新增屬性和方法。

(4)回傳這個新物件(所以建構函式裡面不需要 return )。

JavaScript 的建構函式中可以加入一些成員,可以在建構函式本身上加,也可以在建構函式內部的 this 上加入。透過這兩種方式加入的成員,就分別稱為靜態成員和實例成員。

  • 靜態成員:在建構子本上新增的成員稱為靜態成員,只能由建構子本身來存取

  • 實例成員:在建構函式內部建立的物件成員稱為實例成員,只能由實例化的物件來存取

#舉個栗子:

// 构造函数中的属性和方法称为成员
function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    this.sing = function() {
        console.log('我会唱歌');

    }
}
var ldh = new Star('刘德华', 18);

// 1、实例成员就是构造函数内部通过this添加的成员
// uname、age、sing就是实例成员
// 实例成员只能通过实例化的对象来访问
console.log(ldh.uname); //刘德华
ldh.sing();  //我会唱歌
// 不可以通过构造函数来访问实例成员
console.log(Star.uname); //undefined

Star.sex='男'
// 2、静态成员 在构造函数本身上添加的成员 sex 就是静态成员
// 静态成员只能通过构造函数来访问
console.log(Star.sex); //男
// 静态成员不能通过对象来访问
console.log(ldh.sex);  //undefined
登入後複製

建構函數的問題

建構子方法很好用,但是有浪費記憶體的問題。

es6建構函式只能有一個嗎

我們希望所有的物件都使用同一個函數,這樣就比較節省內存,那麼我們要怎麼做呢?

建構子原型 prototype

建構子透過原型分配的函數是所有物件所共享的。

JavaScript 規定,每個建構函式都有一個 prototype 屬性,指向另一個物件。注意這個 prototype 就是一個對象,這個物件的所有屬性和方法,都會被建構函式所擁有。

我們可以把那些不變的方法,直接定義在 prototype 物件上,這樣所有物件的實例就可以共享這些方法。

列印物件的屬性,查看prototype

 function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    this.sing = function() {
        console.log('我会唱歌');
    }
}
        console.dir(Star);
登入後複製

輸出結果:

es6建構函式只能有一個嗎

  • 原型是什麼 ?

一個對象,我們也稱為 prototype 為原型物件。

  • 原型的作用是什麼 ?

共享方法。

舉個栗子:

function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    // this.sing=function() {
    //     console.log('我会唱歌');
    // }
}
     Star.prototype.sing=function() {
         console.log('我会唱歌');
     }
    var ldh= new Star('刘德华',18);
    var zxy= new Star('张学友',19);
    console.log(ldh.sing===zxy.sing); //采用this添加方法时输出 false 采用prototype添加方法时输出 true
    ldh.sing();
    zxy.sing();
登入後複製

物件原型__proto__

物件都會有一個屬性__proto__指向建構函數的prototype 原型對象,之所以我們物件可以使用建構子prototype 原型物件的屬性與方法,就是因為物件有

__proto__原型的存在。

__proto__物件原型和原型物件prototype 是等價的

__proto__物件原型的意義就在於為物件的查找機制提供一個方向,或者說一條路線,但是它是一個非標準屬性,因此實際開發中,不可以使用這個屬性,它只是內部指向原型物件prototype

es6建構函式只能有一個嗎#

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype.sing=function(){
            console.log('我会唱歌');
        }
        var ldh = new Star('刘德华', 18);
        var zxy = new Star('张学友', 19);
        console.log(ldh); 
        //对象身上系统自己添加一个__proto__ 指向构造函数的原型对象 prototype
        console.log(ldh.__proto__===Star.prototype); //true
        // 方法的查找规则(以sing方法为例):
        // 首先看 实例对象身上是否有 sing 方法,如果有就执行这个对象的sing
        // 如果没有sing 方法,因为有__proto__的存在,就去 构造函数原型对象prototype身上找sing 方法
登入後複製

es6建構函式只能有一個嗎

constructor 构造函数

对象原型__proto__和构造函数(prototype)原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。

es6建構函式只能有一個嗎

constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

   function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        Star.prototype = {
            // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
            constructor: Star,
            sing: function() {
                console.log('我会唱歌');
            },
            movie: function() {
                console.log('我会演电影');
            }
        }
        var ldh = new Star('刘德华', 18);
        console.log(Star.prototype.constructor);
        console.log(ldh.__proto__.constructor);
登入後複製

es6建構函式只能有一個嗎

给原型对象采取对象形式赋值,会覆盖构造函数原型对象原来的内容,就不会有constructor指向当前构造函数

        Star.prototype = {
            sing: function() {
                console.log('我会唱歌');
            },
            movie: function() {
                console.log('我会演电影');
            }
        }
      console.dir(Star);
登入後複製

es6建構函式只能有一個嗎

解决办法:手动的利用constructor指回原来的构造函数

        Star.prototype = {
            // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
            constructor: Star,
            sing: function() {
                console.log('我会唱歌');
            },
            movie: function() {
                console.log('我会演电影');
            }
        }
登入後複製

构造函数、实例、原型对象三者之间的关系

es6建構函式只能有一個嗎

【相关推荐:javascript视频教程编程视频

以上是es6建構函式只能有一個嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板