您好,登錄后才能下訂單哦!
這篇文章主要介紹“JavaScript構造函數怎么自定義”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JavaScript構造函數怎么自定義”文章能幫助大家解決問題。
典型的面向對象編程語言(比如C++和Java),存在“類”(class)這個概念。所謂“類”就是對象的模板,對象就是“類”的實例。但是,在JavaScript語言的對象體系,不是基于“類”的,而是基于構造函數(constructor)和原型鏈(prototype)
‘面向對象編程’的第一步,就是要生成對象。而js中面向對象編程是基于構造函數(constructor)和原型鏈(prototype)的。
前面說過,“對象”是單個實物的抽象。通常需要一個模板,表示某一類實物的共同特征,然后“對象”根據這個模板生成。
js語言中使用構造函數(constructor)作為對象的模板,所謂構造函數,就是提供一個生成對象的模板,并描述對象的基本結構的函數。一個構造函數,可以生成多個對象,每個對象都有相同的結構。
對于JS中的任何一個普通函數,當用new關鍵字來調用時,它就是構造函數。可見與函數定義無關,與調用方法有關。在社區中,通常默契地將函數名首字母大寫來表示該函數以后希望被作為構造函數來使用
作用:構造新對象,設置對象的屬性和方法
ECMAScript提供了多個內置構造函數,如 Object、Array、String、Boolean、Number、Date…等等。
var obj = new Object(); var arr = new Array();
ECMAScript也允許自定義構造函數
構造函數一般首字母會大寫,為了和普通函數區分
一個構造函數可以通過new創建多個實例對象
創建構造函數時,里面的屬性和方法前必須加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(){} //整個構造函數原型 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'} 指向原型鏈,再賦值
構造函數的return
function Dog(){ this.name = "貝貝"; this.bark = function(){ console.log("汪汪汪"); } // return 0; // return []; } var d1 = new Dog(); console.log(d1);//Dog {name: '貝貝', bark: ?} //構造函數不需要return 就可以返回結果
return一個基本數據類型,結果不變,依舊返回一個對象
例:
return 0; console.log(d1);//Dog {name: '貝貝', bark: ?}
return一個復雜數據類型,返回一個復雜數據類型
例:
return []; console.log(d1);//[]
構造函數構造出的對象帶有類型標識
console.log(p1) Person { name: 'zs', age: 12, eating: [Function: eating], } //打印結果有類型標識 //Person 就是類型標識 console.log(p1) {name: 'zs', age: 12, eating:[Function: eating]} //無類型標識的
構造函數的原理(new之后發生了什么)
構造函數之所以能構造出對象,其實JS幫助我們做了很多騷操作。你以為new之后直接執行函數體代碼,其實并不是,事實比我們看到了多了四步
1 自從用new調用函數后,JS引擎就會在內存中創建一個空對象{}
const newObj = {};
2 新對象的__proto__屬性指向構造函數的原型對象
(通俗理解就是新對象隱式原型__proto__鏈接到構造函數顯式原型prototype上。)
newObj.__proto__ = functionName.prototype
3 構造函數內部的this會指向這個新對象(即將構造函數的作用域指向新對象)
this = newObj
4 從上到下執行函數體(只有這步是我們能直觀看到代碼的)
5 返回創造出來的對象(如果構造函數沒有返回對象,則默認返回this。在函數體內部的this指向新創建的內存空間,默認返回 this 就相當于默認返回了該內存空間)
例子:
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引擎幫助我們實現的操作*/ 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;
在構造函數原型上綁定方法節省空間
采用構造函數的確可以批量創建對象,且對象還都有該構造函數的logo,那么構造函數有什么缺點嗎?有的。由于每次函數調用都會創建新的對象,對象中的函數(比如eating)也會創建多份,對于函數而言創建多份沒有必要,能不能共用一個函數呢?
function Person(name, age) { this.name = name; this.age = age; } const p1 = new Person('zs', 12); // 在函數原型上添加方法 Person.prototype.eating = function() { console.log(this.name + ' is eating'); // zs is eating return 5 } console.log(p1.eating()); //5
將方法轉移到構造函數原型上來定義后,對于實例對象p1,依然可以調用eating方法。調用p1的eating方法時,如果p1對象沒有該方法,會去p1對象的原型對象p1.__proto_
找,因為在構造p1時,綁定的原型:p1.__proto__ = Person.prototype
,所以可以找到p1.__proto__.eating
關于“JavaScript構造函數怎么自定義”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。