先文字描述過程,再手撕代碼,最后擴展涉及的知識點
過程
(1)創建一個空對象
(2)繼承指定構造函數(原本繼承的是Object)
(3)將this和調用參數傳給構造器執行(call,apply)
(4)如果構造起沒有手動返回對象,那就返回this指向的那個對象
代碼實現
function Person(name,age){
let this = {} // 隱式
this.name = name
this.age = age
return this // 隱式
}
function newMethod(Parent, ...setValue) {
let newObj = {}; // 創建一個新對象
newObj.__proto__ = Parent.prototype; // 繼承構造函數
Parent.apply(newObj, setValue); // this和參數傳遞給構造函數執行
//如果構造函數沒有手動返回,則返回newObj 否則返回構造函數手動返回的對象
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 }
如果有構造函數本身有手動返回,那么傳入的參數就不起作用
擴展知識點
構造函數繼承構造函數:現在有兩個構造函數Person和Animals,Person要繼承Animals
// 直接繼承
Person.prototype = Animals.prototype
Person.prototype.constructor = Person
對象繼承構造函數: 對象是怎么來的 實質是不是new Object(),實例對象的proto 指向它構造函數的原型對象
newObj.__proto__ = Parent.prototype; //上面例子中對象繼承構造函數的方法
apply和call和bind的區別