JavaScript进阶之模拟new Object()过程
栏目: JavaScript · 发布时间: 5年前
内容简介:前端的入门相对简单,相对于其他方向天花板可能会相对较低。但是在市场上一个优秀的前端依旧是很抢手的。能够站在金字塔上的人往往寥寥无几。目前前端也已经一年半了,在公司的知识栈相对落后,就业形势不容乐观,所以有必要自己琢磨,往中高级前端进阶。后续我将推出《JavaScript进阶系列》,一方面是一个监督自己学习的一个过程,另一方面也会给看到的童鞋一些启发。在ES5中定义一个函数来创建对象,如下:
前端的入门相对简单,相对于其他方向天花板可能会相对较低。但是在市场上一个优秀的前端依旧是很抢手的。能够站在金字塔上的人往往寥寥无几。
目前前端也已经一年半了,在公司的知识栈相对落后,就业形势不容乐观,所以有必要自己琢磨,往中高级前端进阶。后续我将推出《JavaScript进阶系列》,一方面是一个监督自己学习的一个过程,另一方面也会给看到的童鞋一些启发。
JavaScript新建对象的过程
在ES5中定义一个函数来创建对象,如下:
function Person(name){ this.name = name; } var person = new Person("xuan") 复制代码
JavaScript调用 new 的过程主要由下面四步组成:
- 新生成一个对象
- 链接到原型中
- 绑定this
- 返回新对象
下面跟着我按照这个思路来创建对象:
function create(){ //Todo } person = create(Person,"xuan");//create(ObjectName,...arguments) 复制代码
我们使用如上所示的函数来模拟 new 对象。
首先第一步新建一个对象:
function create(){ var obj = new Object(); return obj; } person = create(Person,"xuan"); 复制代码
现在已经创建并返回一个对象,当然现在打印出来肯定是一个普通的对象,毕竟流程还没有走完,我们接着往下看。第二步链接到原型中。
function create(){ var obj = new Object(); var constructor = [].shift.call(arguments); console.log(constructor); console.log(arguments); obj.__proto__ = constructor.prototype; return obj; } person = create(Person,"xuan"); 复制代码
现在把构造函数和参数都打印出来了。没问题!第三步绑定this,如下:
function create() { let obj = new Object(); let constructor = [].shift.call(arguments) obj.__proto__ = constructor.prototype constructor.apply(obj, arguments); console.log(obj); return obj; } person = create(Person,"xuan"); 复制代码
打印结果实现new对象的效果。
现在改一下构造函数代码:
function Person(name){ this.name = name; return { name:"abc" } } var person = new Person("xuan"); console.log(person); console.log(Object.prototype.toString.call(person)); 复制代码
效果如下:
我们执行一下我们构建的函数效果如下:
所以我们要处理第三步绑定this中apply函数的返回值:
function create() { let obj = new Object(); let constructor = [].shift.call(arguments) obj.__proto__ = constructor.prototype //constructor.apply(obj, arguments); let res = constructor.apply(obj, arguments); if(res){ return res; }else{ return obj; } } person = create(Person,"xuan"); 复制代码
完美!
现在我们思考一下这里的res返回值有三种情况:undefined,基本类型,对象。
如果res是undefined时,返回obj;
如果res是基本类型我们也返回obj;
如果res是对象我们返回res对象;
综合一下:
如果返回的res对象是Object类型那么返回res,否则返回obj。当然其他的判断条件也是可以的。最后代码优化如下:
function create() { let obj = new Object(); let constructor = [].shift.call(arguments) obj.__proto__ = constructor.prototype //constructor.apply(obj, arguments); let res = constructor.apply(obj, arguments); return res instanceof Object?res:obj; } person = create(Person,"xuan"); 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 存储过程 – 重新编译后,存储过程运行得很快
- 面试:谈谈你对 MyBatis 执行过程之 SQL 执行过程理解
- 死磕Android_App 启动过程(含 Activity 启动过程)
- 【PHP源码学习】关于$a=1整个过程的gdb过程与相关验证
- Spring的Property配置加载和使用过程及Environment的初始化过程
- [译]从输入URL到页面呈现的超详细过程——第二步:Tags转化成DOM的过程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Markdown 在线编辑器
Markdown 在线编辑器
UNIX 时间戳转换
UNIX 时间戳转换