JavaScript構(gòu)造函數(shù)舉例詳解
典型的面向?qū)ο缶幊陶Z言(比如C++和Java),存在“類”(class)這個概念。所謂“類”就是對象的模板,對象就是“類”的實例。但是,在JavaScript語言的對象體系,不是基于“類”的,而是基于構(gòu)造函數(shù)(constructor)和原型鏈(prototype)
‘面向?qū)ο缶幊?rsquo;的第一步,就是要生成對象。而js中面向?qū)ο缶幊淌腔跇?gòu)造函數(shù)(constructor)和原型鏈(prototype)的。
前面說過,“對象”是單個實物的抽象。通常需要一個模板,表示某一類實物的共同特征,然后“對象”根據(jù)這個模板生成。
js語言中使用構(gòu)造函數(shù)(constructor)作為對象的模板,所謂構(gòu)造函數(shù),就是提供一個生成對象的模板,并描述對象的基本結(jié)構(gòu)的函數(shù)。一個構(gòu)造函數(shù),可以生成多個對象,每個對象都有相同的結(jié)構(gòu)。
對于JS中的任何一個普通函數(shù),當用new關(guān)鍵字來調(diào)用時,它就是構(gòu)造函數(shù)??梢娕c函數(shù)定義無關(guān),與調(diào)用方法有關(guān)。在社區(qū)中,通常默契地將函數(shù)名首字母大寫來表示該函數(shù)以后希望被作為構(gòu)造函數(shù)來使用
作用:構(gòu)造新對象,設(shè)置對象的屬性和方法
ECMAScript提供了多個內(nèi)置構(gòu)造函數(shù),如 Object、Array、String、Boolean、Number、Date…等等。
var obj = new Object(); var arr = new Array();
ECMAScript也允許自定義構(gòu)造函數(shù)
構(gòu)造函數(shù)一般首字母會大寫,為了和普通函數(shù)區(qū)分
一個構(gòu)造函數(shù)可以通過new創(chuàng)建多個實例對象
創(chuàng)建構(gòu)造函數(shù)時,里面的屬性和方法前必須加this,this就表示當前運行時的對象
function Person(name, height) { this.name = name; this.height = height; this.bark = function(fs){ return fs } } var boy = new Person('Keith', 180); console.log(boy); //Person {name: 'Keith', height: 180, bark: ?} console.log(boy.constructor); //f Person(){} //整個構(gòu)造函數(shù)原型 console.log(boy.bark(8)); //8 console.log(boy.name); //'Keith' console.log(boy.height); //180
function Cat1(name){ this.name = name; console.log(this) //先打印 new的時候打印 Cat1 {name: 'kk'} } var cat3 = new Cat1("kk"); console.log(cat3); //后打印 Cat1 {name: 'kk'} 指向原型鏈,再賦值
構(gòu)造函數(shù)的return
function Dog(){ this.name = "貝貝"; this.bark = function(){ console.log("汪汪汪"); } // return 0; // return []; } var d1 = new Dog(); console.log(d1);//Dog {name: '貝貝', bark: ?} //構(gòu)造函數(shù)不需要return 就可以返回結(jié)果
return一個基本數(shù)據(jù)類型,結(jié)果不變,依舊返回一個對象
例:
return 0; console.log(d1);//Dog {name: '貝貝', bark: ?}
return一個復(fù)雜數(shù)據(jù)類型,返回一個復(fù)雜數(shù)據(jù)類型
例:
return []; console.log(d1);//[]
構(gòu)造函數(shù)構(gòu)造出的對象帶有類型標識
console.log(p1) Person { name: 'zs', age: 12, eating: [Function: eating], } //打印結(jié)果有類型標識 //Person 就是類型標識 console.log(p1) {name: 'zs', age: 12, eating:[Function: eating]} //無類型標識的
構(gòu)造函數(shù)的原理(new之后發(fā)生了什么)
構(gòu)造函數(shù)之所以能構(gòu)造出對象,其實JS幫助我們做了很多騷操作。你以為new之后直接執(zhí)行函數(shù)體代碼,其實并不是,事實比我們看到了多了四步
1 自從用new調(diào)用函數(shù)后,JS引擎就會在內(nèi)存中創(chuàng)建一個空對象{}
const newObj = {};
2 新對象的__proto__屬性指向構(gòu)造函數(shù)的原型對象
(通俗理解就是新對象隱式原型__proto__鏈接到構(gòu)造函數(shù)顯式原型prototype上。)
newObj.__proto__ = functionName.prototype
3 構(gòu)造函數(shù)內(nèi)部的this會指向這個新對象(即將構(gòu)造函數(shù)的作用域指向新對象)
this = newObj
4 從上到下執(zhí)行函數(shù)體(只有這步是我們能直觀看到代碼的)
5 返回創(chuàng)造出來的對象(如果構(gòu)造函數(shù)沒有返回對象,則默認返回this。在函數(shù)體內(nèi)部的this指向新創(chuàng)建的內(nèi)存空間,默認返回 this 就相當于默認返回了該內(nèi)存空間)
例子:
function Person(name, age) { this.name = name; this.age = age; this.eating = function() { console.log(this.name + ' is eating'); } } const p1 = new Person('zs', 12); //---------------------------------------------------------------------------- /*實際JS引擎幫助我們實現(xiàn)的操作*/ const newObj = {}; newObj.__proto__ = Person.prototype; this = newObj; this.name = name; this.age = age; this.eating = function() { console.log(this.name + ' is eating'); } return newObj;
在構(gòu)造函數(shù)原型上綁定方法節(jié)省空間
采用構(gòu)造函數(shù)的確可以批量創(chuàng)建對象,且對象還都有該構(gòu)造函數(shù)的logo,那么構(gòu)造函數(shù)有什么缺點嗎?有的。由于每次函數(shù)調(diào)用都會創(chuàng)建新的對象,對象中的函數(shù)(比如eating)也會創(chuàng)建多份,對于函數(shù)而言創(chuàng)建多份沒有必要,能不能共用一個函數(shù)呢?
function Person(name, age) { this.name = name; this.age = age; } const p1 = new Person('zs', 12); // 在函數(shù)原型上添加方法 Person.prototype.eating = function() { console.log(this.name + ' is eating'); // zs is eating return 5 } console.log(p1.eating()); //5
將方法轉(zhuǎn)移到構(gòu)造函數(shù)原型上來定義后,對于實例對象p1,依然可以調(diào)用eating方法。調(diào)用p1的eating方法時,如果p1對象沒有該方法,會去p1對象的原型對象p1.__proto_
找,因為在構(gòu)造p1時,綁定的原型:p1.__proto__ = Person.prototype
,所以可以找到p1.__proto__.eating
總結(jié)
到此這篇關(guān)于JavaScript構(gòu)造函數(shù)的文章就介紹到這了,更多相關(guān)js構(gòu)造函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
webpack本地開發(fā)環(huán)境無法用IP訪問的解決方法
下面小編就為大家分享一篇webpack本地開發(fā)環(huán)境無法用IP訪問的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03使用JavaScript實現(xiàn)按鈕的漣漪效果實例代碼
近來看到個不錯的按鈕點擊效果,當點擊時產(chǎn)生一次水波漣漪效果,挺好玩的,下面這篇文章主要給大家介紹了關(guān)于使用JavaScript實現(xiàn)按鈕漣漪效果的相關(guān)資料,需要的朋友可以參考下2022-11-11復(fù)制網(wǎng)頁內(nèi)容,粘貼之后自動加上網(wǎng)址的實現(xiàn)方法(腳本之家特別整理)
復(fù)制內(nèi)容加網(wǎng)址的功能,自06年腳本之家將這個功能發(fā)布并通過blueidea宣傳以后,現(xiàn)如今很多網(wǎng)站都使用上了, 當初我們也由這個功能帶來很多外鏈2014-10-10smartupload實現(xiàn)文件上傳時獲取表單數(shù)據(jù)(推薦)
這篇文章主要介紹了smartupload實現(xiàn)文件上傳時獲取表單數(shù)據(jù)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-12-12javascript實現(xiàn)用戶管理系統(tǒng)
這篇文章主要為大家詳細介紹了javascript實現(xiàn)用戶管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06Express實現(xiàn)前端后端通信上傳圖片之存儲數(shù)據(jù)庫(mysql)傻瓜式教程(二)
這篇文章主要介紹了Express實現(xiàn)前端后端通信上傳圖片之存儲數(shù)據(jù)庫(mysql)傻瓜教程(二)的相關(guān)資料,需要的朋友可以參考下2015-12-12對frameset、frame、iframe的js操作示例代碼
父框架到子框架的引用、子框架到父框架的引用、兄弟框架間的引用、不同層次框架間的互相引用具體實現(xiàn)如下,有此需求的朋友可以參考下2013-08-08