我們都曉得,運用new
后可返回一個對象,一般用於實例化一個“類”。
用法:
function Student (name, age) {
this.name = name;
this.age = age;
}
Student.prototype.sayName = function() {
console.log('I am '+ this.name);
}
const person =new Student('小明');
person.sayName(); // I am 小明
題目剖析
起首我們剖析一下,手動完成new須要什麼。
- 建立一個函數,可返回一個新的對象
- 須要訪問到
Student
組織函數里的屬性 - 須要訪問到
Student.prototype
中的屬性和要領
詳細步驟剖析
一、參數通報
若要完成上面代碼的雷同效果,起首明白須要一個“類”的參數,以及別的參數(如name
)。
js 的函數參數異常天真,形參數目可不肯定(運用...args
),也可不給出。函數中有一個 與生俱來的arguments
對象,具有length
屬性,但不是數組,所以不可運用數組要領。
arguments
簡樸剖析
下述代碼中的輸出語句效果即為所傳實參的鳩合:
{ ‘0’: [Function: Student], ‘1’: ‘小明’, ‘2’: 18 }
function objectFactory() {
console.log(arguments);
}
const person = objectFactory(Student, '小明',18);
二、要領完成
1.獲得 Student
類的組織函數
由前面 arguments
簡樸剖析可知,arguments
中的第一個參數即為Student
的組織函數。上面說到,arguments 並不是數組,那我們怎樣獲得第一項呢?
兩種要領:[].shift.call(arguments)
或 Array.from(arguments)
var Constructor = [].shift.call(arguments);
2.建立一個新的對象
建立一個新的對象異常簡樸,以下:
const obj = new Object();
3.設置新對象的 __proto__
屬性
__proto__
是對象的私有屬性,指向組織該對象的組織函數的原型。所以此步須將新的對象的此屬性指向 Constructor
的原型。
obj.__proto__ = Constructor.prototype;
4.獲得組織函數上的 this 屬性
若要實例化一個“類”,則必需挪用其組織函數,在實行組織函數時,其 this
的值是動態的變化的,即為當前挪用該函數的對象。
但是這裡有個題目,若此時直接挪用組織函數並傳值
Constructor(arguments);
終究效果將為undefined
。
這是為何呢?
原因是組織函數中的 this
並沒有指向當前的新對象,此時apply()
要領便可圓滿處理這個題目(call()
要領也可),詳細的apply()
的運用及apply()
與call()
的異同可參照大神文章。
效果:
function objectFactory(){
var Constructor = [].shift.call(arguments);
var obj = new Object();
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
return obj;
}
const person = objectFactory(Student, '小明', 18);
person.sayName(); // I am 小明
完畢
關於手動完成new
的進修,原型的觀點更清楚了,在詳細的完成過程當中也進修到了shift
、call
、apply
等要領的一些運用。收成頗豐。