您好,登錄后才能下訂單哦!
這篇文章主要講解了“es6構造函數是不是只能有一個”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“es6構造函數是不是只能有一個”吧!
對,每個類只能有一個構造函數,如果包含多個構造函數,那么會拋出異常。構造函數是一種特殊的函數,主要用來初始化對象,即為對象成員變量賦初始值;使用構造函數時要注意兩點:1、構造函數用于創建某一類對象,其首字母要大寫;2、構造函數要和new一起使用才有意義。
本教程操作環境: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
構造函數的問題
構造函數方法很好用,但是存在浪費內存的問題。
我們希望所有的對象使用同一個函數,這樣就比較節省內存,那么我們要怎樣做呢?
構造函數原型 prototype
構造函數通過原型分配的函數是所有對象所共享的。
JavaScript 規定,每一個構造函數都有一個 prototype 屬性,指向另一個對象。注意這個 prototype 就是一個對象,這個對象的所有屬性和方法,都會被構造函數所擁有。
我們可以把那些不變的方法,直接定義在 prototype 對象上,這樣所有對象的實例就可以共享這些方法。
打印對象的屬性,查看prototype
function Star(uname, age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log('我會唱歌');
}
}
console.dir(Star);
輸出結果:
原型是什么 ?
一個對象,我們也稱為 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
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 方法
constructor 構造函數
對象原型__proto__和構造函數(prototype)原型對象里面都有一個屬性 constructor 屬性 ,constructor 我們稱為構造函數,因為它指回構造函數本身。
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);
給原型對象采取對象形式賦值,會覆蓋構造函數原型對象原來的內容,就不會有constructor指向當前構造函數
Star.prototype = {
sing: function() {
console.log('我會唱歌');
},
movie: function() {
console.log('我會演電影');
}
}
console.dir(Star);
解決辦法:手動的利用constructor指回原來的構造函數
Star.prototype = {
// 如果我們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構造函數
constructor: Star,
sing: function() {
console.log('我會唱歌');
},
movie: function() {
console.log('我會演電影');
}
}
構造函數、實例、原型對象三者之間的關系
感謝各位的閱讀,以上就是“es6構造函數是不是只能有一個”的內容了,經過本文的學習后,相信大家對es6構造函數是不是只能有一個這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。