先文字描述過程像捶,再手撕代碼,最后擴展涉及的知識點
過程
(1)創(chuàng)建一個空對象
(2)繼承指定構(gòu)造函數(shù)(原本繼承的是Object)
(3)將this和調(diào)用參數(shù)傳給構(gòu)造器執(zhí)行(call,apply)
(4)如果構(gòu)造起沒有手動返回對象桂对,那就返回this指向的那個對象
代碼實現(xiàn)
function Person(name,age){
let this = {} // 隱式
this.name = name
this.age = age
return this // 隱式
}
function newMethod(Parent, ...setValue) {
let newObj = {}; // 創(chuàng)建一個新對象
newObj.__proto__ = Parent.prototype; // 繼承構(gòu)造函數(shù)
Parent.apply(newObj, setValue); // this和參數(shù)傳遞給構(gòu)造函數(shù)執(zhí)行
//如果構(gòu)造函數(shù)沒有手動返回,則返回newObj 否則返回構(gòu)造函數(shù)手動返回的對象
if(!Parent()){
return newObj
} else {
return Parent()
}
}
console.log(newMethod(Person,'lihao', 21 )) // Person { name: 'lihao', age: 21 }
ok如果上面的代碼手動返回一個對象
function Person(name,age){
this.name = name
this.age = age
return { // 手動返回
name: 'jidaoyan',
age: 23
}
}
console.log(newMethod(Person,'lihao', 21 )) // { name: 'jidaoyan', age: 23 }
如果有構(gòu)造函數(shù)本身有手動返回鸠匀,那么傳入的參數(shù)就不起作用
擴展知識點
構(gòu)造函數(shù)繼承構(gòu)造函數(shù):現(xiàn)在有兩個構(gòu)造函數(shù)Person和Animals蕉斜,Person要繼承Animals
// 直接繼承
Person.prototype = Animals.prototype
Person.prototype.constructor = Person
對象繼承構(gòu)造函數(shù): 對象是怎么來的 實質(zhì)是不是new Object(),實例對象的proto 指向它構(gòu)造函數(shù)的原型對象
newObj.__proto__ = Parent.prototype; //上面例子中對象繼承構(gòu)造函數(shù)的方法
apply和call和bind的區(qū)別