咱們都知道,使用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須要什麼。ruby
Student
構造函數裏的屬性Student.prototype
中的屬性和方法若要實現上面代碼的相同效果,首先明確須要一個「類」的參數,以及其它參數(如name
)。
js 的函數參數很是靈活,形參數量可不肯定(使用...args
),也可不給出。函數中有一個 與生俱來的arguments
對象,具備length
屬性,但不是數組,因此不可以使用數組方法。app
arguments
簡單分析下述代碼中的輸出語句結果即爲所傳實參的集合:函數
{ '0': [Function: Student], '1': '小明', '2': 18 }學習
function objectFactory() { console.log(arguments); } const person = objectFactory(Student, '小明',18);
Student
類的構造函數由前面 arguments
簡單分析可知,arguments
中的第一個參數即爲Student
的構造函數。上面說到,arguments 並不是數組,那咱們如何獲得第一項呢?this
兩種方法:[].shift.call(arguments)
或 Array.from(arguments)
prototype
var Constructor = [].shift.call(arguments);
建立一個新的對象很是簡單,以下:code
const obj = new Object();
__proto__
屬性__proto__
是對象的私有屬性,指向構造該對象的構造函數的原型。因此此步須將新的對象的此屬性指向 Constructor
的原型。對象
obj.__proto__ = Constructor.prototype;
若要實例化一個「類」,則必須調用其構造函數,在執行構造函數時,其 this
的值是動態的變化的,即爲當前調用該函數的對象。get
但是這裏有個問題,若此時直接調用構造函數並傳值
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
等方法的一些使用。收穫頗豐。