最近天氣好冷,上下班騎着小電驢,風吹得整我的都是冰冰的,小夥伴要注意保暖,千萬別冷到了。markdown
咱們先來看看MDN上給出的簡介app
❝new 運算符建立一個用戶定義的對象類型的實例或具備構造函數的內置對象的實例。函數
❞
new 關鍵字你們都不陌生,用來給構造函數建立實例的,可是 new 它到底幹了些什麼,可能就不是很清楚了,下面我來給你們解開 new 的神祕面紗。oop
咱們先來複習下 new 的使用,來看看 new 的功能,先知道 new 作了什麼事情才能更好的去實現它。測試
function Pig(name, age) {
this.name = name;
this.age = age;
this.habit = '吃棒棒糖';
}
Pig.prototype.sayName = function() {
console.log('我叫' + this.name);
}
Pig.prototype.skill = '降龍十巴掌!(๑•̀ㅂ•́) ✧';
let GGBond = new Pig("豬豬俠", 13);
console.log(GGBond); // Pig { name: '豬豬俠', age: 13, habit: '吃棒棒糖', __proto__: Object }
console.log(GGBond.name); // 豬豬俠
console.log(GGBond.skill); // 降龍十巴掌!(๑•̀ㅂ•́) ✧
GGBond.sayName(); // 我叫豬豬俠
複製代碼
經過上面的栗子咱們能夠看到 new 出來的實例對象:ui
經過上面的例子咱們已經明白了 new 的功能了,可是具體 new 是怎麼作到的呢?讓咱們來看看MDN。this
❝❞
- 建立一個空的簡單JavaScript對象(即{});
- 連接該對象(設置該對象的constructor)到另外一個對象 ;
- 將步驟1新建立的對象做爲this的上下文 ;
- 若是該函數沒有返回對象,則返回this。
咱們跟着這個功能來一步步實現 new 吧!spa
建立一個空的簡單JavaScript對象(即{});prototype
function myNew(Ctor, ...args) {
let obj = {};
}
複製代碼
連接該對象(設置該對象的constructor)到另外一個對象 ;code
function myNew(Ctor, ...args) {
let obj = {};
obj.__proto__ = Ctor.prototype;
}
複製代碼
將步驟1新建立的對象做爲this的上下文 ;
function myNew(Ctor, ...args) {
let obj = {};
obj.__proto__ = Ctor.prototype;
const result = Ctor.apply(obj, args);
}
複製代碼
若是該函數沒有返回對象,則返回this。
function myNew(Ctor, ...args) {
let obj = {}; // 建立實例對象
obj.__proto__ = Ctor.prototype; // 原型鏈繼承
const res = Ctor.apply(obj, args); // 修改 this 指向實例
if (/^(object|function)$/.test(typeof res)) return res; // 構造函數返回的是對象就直接該返回該結果
return obj; // 不然返回實例
}
複製代碼
代碼寫完了,咱們來執行上面的例子來看下是否和原生 new 表現一致
function Pig(name, age) {
this.name = name;
this.age = age;
this.habit = '吃棒棒糖';
}
Pig.prototype.sayName = function() {
console.log('我叫' + this.name);
}
Pig.prototype.skill = '降龍十巴掌!(๑•̀ㅂ•́) ✧';
function myNew(Ctor, ...args) {
let obj = {}; // 建立一個實例對象
obj.__proto__ = Ctor.prototype;
const res = Ctor.apply(obj, args);
if (/^(object|function)$/.test(typeof res)) return res;
return obj;
}
let myGGBond = myNew(Pig, "豬豬俠", 13);
console.log(myGGBond); // Pig { name: '豬豬俠', age: 13, habit: '吃棒棒糖', __proto__: Object }
console.log(myGGBond.name); // 豬豬俠
console.log(myGGBond.skill); // 降龍十巴掌!(๑•̀ㅂ•́) ✧
myGGBond.sayName(); // 我叫豬豬俠
// 測試返回函數
function Dog(name) {
this.name = name;
this.habit = '吃骨頭';
return function() {
console.log('隨便輸出點什麼吧');
}
}
let myDog = myNew(Dog, '金毛');
console.log(myDog); // ƒ () {...}
// 測試返回對象
function Cat(name) {
this.name = name;
this.habit = '吃魚';
return {
name
}
}
let myCat = myNew(Cat, '黑貓警長');
console.log(myCat); // { name: '黑貓警長' }
複製代碼
能夠看到和原生的 new 結果是同樣的。
很是感謝各位能閱讀到這裏,以爲有幫助的話不妨點個贊,你的支持是對我對最大的鼓勵。