new 能夠實現一個對象繼承構造函數的屬性以及方法數組
舉個例子:bash
function Parent(name,age){
this.name = name;
this.age = age;
}
Parent.prototype.sayName = function(){
console.log(`my name is ${this.name}`)
}
let child = new Parent('js',18);
console.log(child.name); // js
console.log(child.age); // 18
child.sayName(); // my name is js
複製代碼
從這個案例,能夠看到實例childapp
1.繼承了構造函數裏面的屬性函數
2.能夠訪問到構造函數prototype中的屬性測試
經過下面這個圖來直觀感覺一下,這裏涉及到js原形以及原型鏈,先提早補腦一下 ui
child.constructor === Parent //true
child._proto === Parent.prototype //true
Parent.prototype.constructor === Parent //true
複製代碼
接下來按照剛剛的例子結合上面的這張圖片來實現new 內部是怎麼的實現過程:this
function newFactory(){
let obj = new Object(),
context = Array.prototype.shift.call(arguments);
obj.__proto__ = context.prototype;
context.apply(obj,arguments);
return obj;
}
複製代碼
接下來測試一下spa
function Parent(name,age){
this.name = name;
this.age = age;
}
Parent.prototype.sayName = function(){
console.log(`my name is ${this.name}`)
}
function newFactory(){
let obj = new Object(),
context = Array.prototype.shift.call(arguments);
obj.__proto__ = context.prototype;
context.apply(obj,arguments);
return obj;
}
let child = newFactory(Parent,'js','18')
console.log(child.name); // js
console.log(child.age); // 18
child.sayName(); // my name is js
複製代碼
到這一步咱們已經完成了80%,由於還有種狀況咱們沒有考慮到,當構造函數有返回值的時候,實例化的對象會怎麼?prototype
function Parent(name,age){
this.age = age;
this.sex = 'boy'
return {
name:name,
address:'china'
}
}
var child = new Parent('js','18')
console.log(child.name); // js
console.log(child.age); // undefined
console.log(child.sex); // undefined
console.log(child.address); // china
複製代碼
經過上面這個案例,能夠看出當構造函數返回了一個對象的化,實例child只能訪問到返回對象的屬性,那若是返回的是基本類型呢?code
function Parent(name,age){
this.age = age;
this.sex = 'boy'
return 'china';
}
var child = new Parent('js','18')
console.log(child.name); // undefined
console.log(child.age); // 18
console.log(child.sex); // boy
console.log(child.address); // undefined
複製代碼
從這個案例能夠看出來當構造函數返回值是基本類型的時候,跟沒有返回值同樣。
終極版 四大步驟:
一、建立一個空對象,而且 this 變量引用該對象,// let obj = new Object();
二、繼承了函數的原型。// obj.proto = func.prototype;
三、屬性和方法被加入到 this 引用的對象中。並執行了該函數func// func.call(target);
四、新建立的對象由 this 所引用,而且最後隱式的返回 this 。// 若是func.call(target)返回的res是個對象或者function 就返回它
function newFactory(){
let obj = new Object(),
context = Array.prototype.shift.call(arguments);
obj.__proto__ = context.prototype;
let res = context.apply(obj,arguments);
if ((typeof res === "object" || typeof res === "function") && res !== null) {
return res;
}
return obj;
}
複製代碼