new
運算符是建立一個用戶定義的對象類型的實例或具備構造函數的內置對象的實例,其建立過程以下:javascript
JavaScript對象
(即{})this
的上下文this
舉個栗子:java
function Person(name,age){ this.name = name; this.age = age; this.habit = "swim"; } Person.prototype.sex = 'female'; Person.prototype.sayHello = function(){ console.log('Hello!My name is ' + this.name); } var person = new Person('Youxuan','20'); console.log(person.name); //Youxuan console.log(person.habit); //swim console.log(person.sex); //female person.sayHello(); //Hello!My name is Youxuan
從上述內容中,能夠看出實例訪問到Person構造函數裏的屬性,
也能夠訪問到Person.prototype
裏的屬性;
所以,咱們能夠嘗試模擬一下new
的實現方法,先來回顧一下new是如何使用的數組
function Person(){ ... } var person = new Person(...); var person = newObject(...);
由於new的結果是一個對象,因此在實現new的過程當中,也要生成一個新的對象。咱們先將這個對象命名爲obj,由於obj也具備Person構造函數
的屬性,全部要經過調用父類,繼承父類實例的方式,來給obj添加新屬性。微信
回顧上一篇文章,咱們講解了原型和原型鏈
,把obj的proto指向構造函數Person的原型對象prototype
,此時便創建了obj對象的原型鏈:app
obj->Person.prototype->Object.prototype->null,實例以此關係來訪問原型上的屬性函數
function newObject(){ var obj = new Object(); Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; Constructor.apply(obj,arguments); return obj; }
在以上內容中,經過new Object()建立了一個對象obj。this
取出第一個參數,就是咱們要傳入的構造函數。由於shift會修改原數組,因此arguments
會被去除第一個參數。spa
將obj的原型指向構造函數,這樣obj就能夠訪問到構造函數原型中的屬性。prototype
利用apply
,改變構造函數this
指向到新建對象,這樣obj就能訪問到構造函數中的屬性,而後返回obj。code
如今,咱們寫一段代碼來驗證一下效果:
function Person(name,age){ this.sex = 'female'; this.age = age; return { name: name, habit: 'swim' } } var person = new Person('Youxuan','20'); console.log(person.name); //Youxuan console.log(person.habit); //swim console.log(person.sex); //undefined console.log(person.age); //undefined
以上代碼中,構造函數返回了一個對象
,在實例person中只能訪問返回的對象中的屬性。
並且另需注意,這裏返回的是一個對象,倘若須要返回一個基本類型的數據時該怎麼辦呢?
function Person(name,age){ this.sex = 'female'; this.age = age; return 'Beauty on my face' } var person = new Person('Youxuan','20'); console.log(person.name); //undefined console.log(person.habit); //undefined console.log(person.sex); //female console.log(person.age); //20
這時結果跟上次徹底相反,儘管此次有返回值,可是至關於沒有對返回值進行處理。
因此仍需判斷返回值是否是一個對象,若是是一個對象,就返回這個對象;若是不是一個對象,那就將它直接返回:
function newObject(){ var obj = new Object(); Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; var demo = Constructor.apply(obj,arguments); return typeof demo === 'object' ? demo : obj; }
至此就模擬實現了new
操做符的效果,主要原理就是原型鏈
和apply
繼承。
對此你有什麼感覺呢,歡迎添加微信進行交流。