可以描述 new一个对象的详细过程,手动实现一个 new操作符

1. new 一个对象的详细过程:(原文地址

首先我们看下new Person输出什么?

var Person = function(name, age) {
this.name = name;
this.age = age;
};
Person.prototype.show = function() {
console.log(this.name, this.age);
};
var p = new Person("bella", 10);
console.log(p);

有属性name, age 和 __proto__

__proto__里面有原型方法show,constructor, __proto__

然后我们再输出构造器Person.prototype:

对比一下,发现p的__proto__的值就是构造函数Person的prototype的属性值。

因此new操作符创建对象可以分为以下四个步骤:

  ① 创建一个空对象;

  ② 链接到原型(将所创建对象的__proto__属性值设为构造函数的prototype属性值);

  ③ 绑定this(构造函数中的this指向新对象并且调用构造函数);

  ④ 返回新对象。

因此上面的过程就可以等同于下面的过程:

var Person = function(name, age) {
this.name = name;
this.age = age;
};
Person.prototype.show = function() {
console.log(this.name, this.age);
};
// var p = new Person("bella", 10);
var p = {};
p.__proto__ = Person.prototype;
Person.call(p, "balle", 10);
console.log(p);

2. 手动实现一个new操作符:(原文地址

要手动实现 new 操作符,就要明白new操作符做了什么事,如 上面 总结的new操作符创建对象的四个步骤。

这样我们就可以实现一个new方法了:

function realizeNew () {
//创建一个新对象
let obj = {};
//获得构造函数
let Con = [].shift.call(arguments);
//链接到原型(给obj这个新生对象的原型指向它的构造函数的原型)
obj.__proto__ = Con.prototype;
//绑定this
let result = Con.apply(obj,arguments);
//确保new出来的是一个对象
return typeof result === "object" ? result : obj
}

[].shift.call(arguments)的作用是将调用realizeNew方法的第一个值拿出来:

我们实现的realizeNew()需要传入的参数是:构造函数 + 属性

首先创建一个新对象,

然后通过 arguments 类数组我们可以知道参数中包含了构造函数以及我们调用create时传入的其他参数,接下来就是要想如何得到其中这个构造函数和其他参数,由于arguments是类数组,没有直接的方法可以供其使用,我们可以有以下两种方法:

  1)Array.form(arguments).shift();转换成数组,使用数组方法shift将第一项弹出

  2)[].shift().call(arguments);通过call()让arguments能够借用shift()方法

绑定this的时候需要注意:

  1)给构造函数传入属性,注意构造函数的this属性;

  2)参数传进Con对obj的属性复制,this要指向obj对象;

  3)在Con内部手动指定函数执行时的this使用call、apply实现

最后需要返回一个对象

测试:

function Person (name,age){
this.name = name;
this.age = age;
this.say = function () {
console.log("I am " + this.name)
}
} //通过new创建构造实例
let person1 = new Person("Curry",18);
console.log(person1.name); //"Curry"
console.log(person1.age); //
person1.say(); //"I am Curry' //通过realize()方法创造实例
let person2 = realizeNew (Person,"Curry",18);
console.log(person2.name); //"Curry"
console.log(person2.age); //
person2.say(); //"I am Curry'

前端知识体系:JavaScript基础-原型和原型链-new一个对象的详细过程,手动实现一个 new操作符的更多相关文章

  1. web前端知识体系总结

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  2. 自己总结的web前端知识体系大全【欢迎补充】

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  3. web前端知识体系大全

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  4. web前端知识体系小结(转)

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  5. Web前端知识体系精简

    Web前端技术由html.css和javascript三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言.而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学习新的知 ...

  6. 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!

    前言 见解有限,如有描述不当之处,请帮忙指出,如有错误,会及时修正. 为什么要梳理这篇文章? 最近恰好被问到这方面的问题,尝试整理后发现,这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目. ...

  7. Web前端知识体系

    看到一篇不错的文章,拿来收藏和分享. 原文:http://mp.weixin.qq.com/s/UFTfdE7LYhHquWEzwZKLCQ Web前端技术由html.css和 javascript三 ...

  8. web前端知识体系大全【欢迎补充】

    大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的是想要颠覆人 ...

  9. web前端知识体系大全【转载】

    自己总结的web前端知识体系大全[欢迎补充]   1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在 ...

随机推荐

  1. Python小技巧:使用一行命令把你的电脑变成服务器

    不知道你有没有遇到这么一种情况,就是你有时候想要把电脑上的一些东西传输到你的手机或者 Pad ,你要么需要使用数据线连接到电脑,有时候还要装各种驱动才可以进行数据传输,要么需要借助第三方的工具,在局域 ...

  2. ${__setProperty 等常见jmeter参数相关博客汇总

    jmeter 控制线程组执行顺序   这个要配合全局变量.if和while来实现BeanShell取样器,全局变量:${__setProperty(newswitch,${switch1},)}if条 ...

  3. 关于Python的导入覆盖解决办法

    这种问题一般来说还是不会引起的,可能会出现在datetime和time这样类型的模块中. 例如: import datetime from datetime import datetime 如果写在一 ...

  4. Tomcat与WAS应用中间件差异化分析研究

    --转载 http://blog.chinaunix.net/uid-25723371-id-5759072.html 目前我们在使用的基于JAVA的提供逻辑展现应用中间件有两种,一种是以商用软件WA ...

  5. ASP.NET WEB应用程序(.network4.5)MVC Razor视图引擎2 动态数据的呈现

    https://www.cnblogs.com/cynchanpin/p/7065098.html 在MVC3開始.视图数据能够通过ViewBag属性訪问.在MVC2中则是使用ViewData.MVC ...

  6. [NOIP2018模拟赛10.25]瞎搞报告

    闲扯 最近有点颓,都修到好晚,早上起来和吔shi一样难受 忍着困意把题面看完,发现啥也不会,又是一场写暴力的模拟赛 T1发现似乎可以DP,顺手码了个 T2像个最小瓶颈路板子,但是只做过N^2算法的.. ...

  7. 货币转换B

    描述 人民币和美元是世界上通用的两种货币之一,写一个程序进行货币间币值转换,其中:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮ ...

  8. JavaScript--Function对象(函数)的声明和作用域

    Funtion 封装了可重复使用的代码块对象,函数名是一个引用函数对象的变量 声明提前:在程序开始执行之前,将var 变量和function函数提前声明 但赋值并不会提前 它的三种创建方法: 创建1 ...

  9. Go 结构体的使用

    结构体是用户定义的类型,表示若干个字段(Field)的集合.有时应该把数据整合在一起,而不是让这些数据没有联系.这种情况下可以使用结构体. 例如,一个职员有 firstName.lastName 和  ...

  10. ADF一个EO的事物提交周期

    客户端通过传递键对象调用实体定义的findByPrimaryKey(),获得EO.ADF框架首先检查实体缓存, 如果在实体缓存中没有找到实体,就执行SQL SELECT查询,从数据库读取行.示例如下: ...