可以描述 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学习路线图(2020年最新版)

    这是我刚开始学习python时的一套学习路线,从入门到上手.(不敢说精通,哈哈~) 希望对大家有帮助哈~ 一.Python入门.环境搭建.变量.数据类型 二.Python运算符.条件结构.循环结构 三 ...

  2. 乐字节Java|GC垃圾回收机制、package和import

    本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...

  3. Mstering QT5 chapter1

    涉及到c++ 14新特性: lambda,autovariables. A basic .pro file generally contains: 1) Qt modules used (core, ...

  4. [windows官网]虚拟地址空间

    虚拟地址空间 https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/virtual-address-spac ...

  5. java日志框架系列(9):logback框架过滤器(filter)详解

    过滤器放在了logback-classic模块中. 1.logback-classic模块中过滤器 分类(2种):常规过滤器.TurboFilter过滤器. 1.常规过滤器 常规过滤器可以通过自定义进 ...

  6. ora00972标识符过长

    oracle10G对于表名的长度限制是30个字节 表名超过30结果不能创建,提示ora00972-标识符过长. 需要将表名控制在30个字节以内

  7. time() 函数时间不同步问题

    1.时区设置问题 处理方法:编辑php.ini  搜索 “timezone” 改写为 PRC 时区 2.服务器时间不同步 处理方法:设置服务器时间和本地时间进行同步

  8. Python senium 中页面属性

    1.通过id定位元素2.通过class_name定位元素3.通过tag_name定位元素4.通过name定位元素5.通过link文字精确定位元素6.通过link文字模糊定位元素7.通过CSS定位元素8 ...

  9. python — 索引与pymysql模块

    1. 索引 1.1 索引原理 1.什么是索引 ?-- 目录 索引就是建立起的一个在存储表阶段就有的一个存储结构,能在查询的时候加速. 2.索引的重要性: 读写比例 为 10:1,所有读(查询)的速度就 ...

  10. MySQL Sakila示例数据库

    Table of Contents 1 Preface and Legal Notices 2 Introduction 3 History 4 Installation 5 Structure    ...