new 關鍵詞的主要做用就是執行一個構造函數、返回一個實例對象,在 new 的過程當中,根據構造函數的狀況,來肯定是否能夠接受參數的傳遞。下面咱們經過一段代碼來看一個簡單的 new 的例子
new 操做符能夠幫助咱們構建出一個實例,而且綁定上 this,內部執行步驟可大概分爲如下幾步:
若是不用 new 這個關鍵詞,結合上面的代碼改造一下,去掉 new,會發生什麼樣的變化呢?咱們再來看下面這段代碼
// 'use strict'; function Person() { this.name = "江小白"; } var p = Person(); console.log(p); //undefined console.log(name) //江小白 console.log(p.name); // Cannot read property 'name' of undefined
function Person() { this.nem = "江小白"; return { age: 22 }; } var p = new Person(); console.log(p); //{ age: 22 } console.log(p.name); //undefined console.log(p.age); //22
經過這段代碼又能夠看出,當構造函數最後 return 出來的是一個和 this 無關的對象時,new 命令會直接返回這個新對象,而不是經過 new 執行步驟生成的 this 對象app
可是這裏要求構造函數必須是返回一個對象,若是返回的不是對象,那麼仍是會按照 new 的實現步驟,返回新生成的對象。接下來仍是在上面這段代碼的基礎之上稍微改動一下函數
function Person(){ this.name = '江小白'; return 'tom'; } var p = new Person(); console.log(p) // {name: '江小白'} console.log(p.name) // 江小白
💝 所以咱們總結一下:
new 關鍵詞執行以後老是會返回一個對象,要麼是實例對象,要麼是 return 語句指定的對象
// 手寫模擬new function myNew(fn, ...args) { if (typeof fn !== 'function') { throw 'fn mast be a function'; } // 1. 用new Object()建立一個對象obj var obj = new Object(); // 2. 給該對象的__proto__賦值爲fn.prototype,即設置原型鏈 obj.__proto__ = Object.create(fn.prototype); // 3. 執行fn,並將obj做爲內部this。使用 apply, // 改變構造函數 this 的指向到新建的對象, // 這樣 obj 就能夠訪問到構造函數中的屬性 var result = fn.apply(obj, args); // 4. 若是fn有返回值,則將其做爲new操做返回,不然返回obj return result instanceof Object ? result : obj; }
// test function Person(...args) { console.log(args) } // 使用內置函數new var person1 = new Person(1,2) console.log(person1) // 使用手寫的new,即create var person2 = myNew(Person, 1, 2) console.log(person2)
new 被調用後大體作了哪幾件事情