2021年是全新的一年,是一個積極性向上富有活力的一年,讓我們起航開啓新的征程,一切的一切都重新開始,今天講一講關於new的事情,大家一起加油!
一、定義
new 運算符創建一個用户定義的對象類型的實例或具有構造函數的內置對象的實例。
二、語法
new constructor[([arguments])]
constructor一個指定對象實例的類型的類或函數。
arguments一個用於被constructor調用的參數列表。
三、例子
例一、創建一個自定義類
/**
* 關鍵字function創建類
*/
function YearFunction(){
}
let yearFn = new YearFunction();
/**
* 關鍵字class創建類
*/
class YearClass{
}
let yearCs = new YearClass();
console.log(yearFn);
console.log(yearCs);
總結
有兩種方式創建類,一種用關鍵字function,另一種用關鍵字class。class可以作為function創建類的一種語法糖。
例二、創建具有屬性的自定義類
function YearFunction(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
let yearFn = new YearFunction(2021, 1, 1);
class YearClass{
constructor(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
}
let yearCs = new YearClass(2021, 1, 1);
console.log(yearFn);
console.log(yearCs);
總結
在定義屬性時,function直接寫在方法體內部,class是寫在constructor構造函數內容。
例三、創建具有函數的自定義類
function YearFunction(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
YearFunction.prototype.getYear = function getYear(){
return this.year;
}
let yearFn = new YearFunction(2021, 1, 1);
class YearClass{
constructor(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
getYear(){
return this.year;
}
}
let yearCs = new YearClass(2021, 1, 1);
console.log(yearFn);
console.log(yearCs);
總結
在定義方法時,function需要在prototype屬性上顯示聲明函數,class在類的內部定義。細心的你,function聲明的方法多了一個prototype,這是class創建類比function的優化的地方。
例四、實例與類的關係
class YearClass{
constructor(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
}
let yearCs = new YearClass(2021, 1, 1);
console.log(yearCs instanceof YearClass); // true
console.log(yearCs instanceof Object); // true
console.log(yearCs.constructor === YearClass); // true
console.log(yearCs.constructor === Object); // false
console.log(yearCs.__proto__ === YearClass.prototype); // true 不推薦
console.log(Object.getPrototypeOf(yearCs) === YearClass.prototype); // true 推薦
總結
對象的constructor指向類,對象的__proto__指向類的prototype。
例五、不聲明參數
class YearClass{
constructor(year = 2000, month = 1, day = 1){
this.year = year;
this.month = month;
this.day = day;
}
}
let yearCsUnparams = new YearClass;
let yearCsparams = new YearClass(2021, 1, 1);
let yearCsDefparams = new YearClass();
console.log(yearCsUnparams);
console.log(yearCsparams);
console.log(yearCsDefparams);
總結
創建類時,可以顯示聲明參數,還可以忽略參數部分,這時創建對象時使用默認參數。
例六、模擬new的實現
function newFactory(csName){
var obj = new Object();
var CsName = [].shift.apply(arguments);
obj.__proto__ = CsName.prototype;
var result = CsName.apply(obj, arguments);
return typeof result === 'object'?result:obj;
}
function YearFunction(year, month, day){
this.year = year;
this.month = month;
this.day = day;
}
console.log(newFactory(YearFunction, 2021, 1, 1));
console.log(new YearFunction(2021, 1, 1));
總結
當代碼new Year(...)執行時,會發生以下事情:
1、一個繼承自 Year.prototype 的新對象被創建。
2、使用指定的參數調用構造函數Year,並將this綁定到新創建的對象。new Year等同於new Year(),也就是沒有指定參數列表,Year不帶任何參數調用的情況。
3、由構造函數返回的對象就是 new 表達式的結果。如果構造函數沒有顯式返回一個對象,則使用步驟1創建的對象(一般情況下,構造函數不返回值,但是用户可以選擇主動返回對象,來覆蓋正常的對象創建步驟)。
喜歡可以關注微信公眾號“前端咖”