简单介绍一下new

new再熟悉不过了,new后面跟着构造函数,可以创建对象,这个对象的原型指向构造函数的原型对象,说起来可能有点绕,直接看代码吧

function Person(name, age){
this.name = name;
this.age = age;
} let person1 = new Person("张三", 22); console.log(person1.__proto__ === Person.prototype); // true
console.log(person1 instanceof Person); // true

而new后面的构造函数,也可以这样调用

let person2 = new Person;

其实这样写就等同于,不传任何参数调用构造函数

let person2 = new Person();

打印person2可以看到

Person { name: undefined, age: undefined }

一般情况下,构造函数是不定义返回值的,那我们试一试,如果构造函数定义返回值,会怎么样,首先,返回一个字符串

function Person(name, age){
this.name = name;
this.age = age; return "person"
} let person1 = new Person("张三", 22);
let person2 = new Person; console.log(person1); // Person { name: '张三', age: 22 }
console.log(person2); // Person { name: undefined, age: undefined }
console.log(person1.__proto__ === Person.prototype); // true
console.log(person1 instanceof Person) // true

看来构造函数返回字符串没有影响,那返回一个对象呢

function Person(name, age){
this.name = name;
this.age = age; return {
id : "person"
}
} let person1 = new Person("张三", 22);
let person2 = new Person; console.log(person1); // { id: 'person' }
console.log(person2); // { id: 'person' }
console.log(person1.__proto__ === Person.prototype); // false
console.log(person1 instanceof Person) // false

可以看到,如果返回一个对象,那么通过new关键字创建的对象则为构造返回的值,且也不继承于构造的原型对象

手写

了解的差不多了,开始手写

首先定义一个函数名为myNew,参数接收一个function,也就是构造函数,

function myNew(Constructor){
if(typeof Constructor !== "function"){
throw "参数Constructor必须是方法(function)"
}
}

ok,紧接着需要创建一个新的对象,并且这个对象的原型指向的是构造函数的原型对象

所以

function myNew(Constructor){
if(typeof Constructor !== "function"){
throw "参数Constructor必须是方法(function)"
}
let obj = {};
obj.__proto__ = Constructor.prototype;
}

接着,因为执行构造函数的是,需要传参数,并且在构造函数内部会为this赋值,所以我们需要执行构造函数,并且把构造函数内的上下文指向到obj

function myNew(Constructor){
if(typeof Constructor !== "function"){
throw "参数Constructor必须是方法(function)"
}
let obj = {};
obj.__proto__ = Constructor.prototype;
// 获取参数
let params = Array.from(arguments);
// 把参数第一位,也就是构造函数移除
params.shift();
// 执行构造函数,并且吧上下文只设置为obj
Constructor.apply(obj, params); return obj
}

但是我们需要前面提到了,有时候构造函数是可能有返回值的,所以最终代码为

最终源码

function myNew(Constructor){
if(typeof Constructor !== "function"){
throw "参数Constructor必须是方法(function)"
}
let obj = {};
obj.__proto__ = Constructor.prototype;
// 获取参数
let params = Array.from(arguments);
// 把参数第一位,也就是构造函数移除
params.shift();
// 执行构造函数,并且吧上下文只设置为obj
let result = Constructor.apply(obj, params); // 判断构造函数执行返回是不是object,是的话返回这个对象
return typeof result === "object" ? result : obj
}

我们以之前的例子来验证一下

function Person(name, age){
this.name = name;
this.age = age; return "person"
} let person1 = myNew(Person, "张三", 22);
let person2 = myNew(Person); console.log(person1); // Person { name: '张三', age: 22 }
console.log(person2); // Person { name: undefined, age: undefined }
console.log(person1.__proto__ === Person.prototype); // true
console.log(person1 instanceof Person) // true

构造有返回值的时候

function Person(name, age){
this.name = name;
this.age = age; return {
id : "person"
}
} let person1 = myNew(Person, "张三", 22);
let person2 = myNew(Person); console.log(person1); // { id: 'person' }
console.log(person2); // { id: 'person' }
console.log(person1.__proto__ === Person.prototype); // false
console.log(person1 instanceof Person) // false

与前面完全一致

最新文章

  1. 火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版
  2. 解决NetBeans运行web项目时出现的“未能正确设置java DB”问题
  3. android整体架构概述--①
  4. Linux Systemcall Int0x80方式、Sysenter/Sysexit Difference Comparation
  5. 2013年7月份第1周51Aspx源码发布详情
  6. 向Dialog中添加一个新的Menu
  7. uva 10161 Ant on a Chessboard 蛇形矩阵 简单数学题
  8. asp.net WebApi 使用总结
  9. MVC 动态菜单
  10. ASP.NET Core -中间件(Middleware)使用
  11. Oracle查看用户密码过期,修改永不过期
  12. js用currentStyle和getComputedStyle获取css样式(非行间) 兼容ie与火狐
  13. 三星打印机SCX-4824HN全套驱动(打印/扫描)
  14. man 转 pdf _____ jpg 转 pdf
  15. 小程序四:视图之WXSS
  16. win32串口编程
  17. 0329--Scrum团队准备工作
  18. CDN加速-内容分发网络
  19. JavaScript中callee与caller,apply与call解析
  20. CyclicBarrier 简介

热门文章

  1. 自我介绍网页填写表格PHP,JavaScript,html,css代码
  2. springboot-swagger配置
  3. include标签—引用文件路径
  4. 科赫雪花利用python海龟绘图代码
  5. 微信小程序事件绑定
  6. unity 真机调试
  7. photonServer学习之连接数据库
  8. [BUUOJ记录] [SUCTF 2019]CheckIn
  9. nginx的gzip压缩
  10. js map对象处理if