最近天气好冷,上下班骑着小电驴,风吹得整我的都是冰冰的,小伙伴要注意保暖,千万别冷到了。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 结果是同样的。
很是感谢各位能阅读到这里,以为有帮助的话不妨点个赞,你的支持是对我对最大的鼓励。