前端知识体系:JavaScript基础-原型和原型链-new一个对象的详细过程,手动实现一个 new操作符
可以描述 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操作符的更多相关文章
- web前端知识体系总结
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- 自己总结的web前端知识体系大全【欢迎补充】
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- web前端知识体系大全
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- web前端知识体系小结(转)
1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...
- Web前端知识体系精简
Web前端技术由html.css和javascript三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言.而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学习新的知 ...
- 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!
前言 见解有限,如有描述不当之处,请帮忙指出,如有错误,会及时修正. 为什么要梳理这篇文章? 最近恰好被问到这方面的问题,尝试整理后发现,这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目. ...
- Web前端知识体系
看到一篇不错的文章,拿来收藏和分享. 原文:http://mp.weixin.qq.com/s/UFTfdE7LYhHquWEzwZKLCQ Web前端技术由html.css和 javascript三 ...
- web前端知识体系大全【欢迎补充】
大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的是想要颠覆人 ...
- web前端知识体系大全【转载】
自己总结的web前端知识体系大全[欢迎补充] 1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在 ...
随机推荐
- Python学习路线图(2020年最新版)
这是我刚开始学习python时的一套学习路线,从入门到上手.(不敢说精通,哈哈~) 希望对大家有帮助哈~ 一.Python入门.环境搭建.变量.数据类型 二.Python运算符.条件结构.循环结构 三 ...
- 乐字节Java|GC垃圾回收机制、package和import
本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...
- Mstering QT5 chapter1
涉及到c++ 14新特性: lambda,autovariables. A basic .pro file generally contains: 1) Qt modules used (core, ...
- [windows官网]虚拟地址空间
虚拟地址空间 https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/virtual-address-spac ...
- java日志框架系列(9):logback框架过滤器(filter)详解
过滤器放在了logback-classic模块中. 1.logback-classic模块中过滤器 分类(2种):常规过滤器.TurboFilter过滤器. 1.常规过滤器 常规过滤器可以通过自定义进 ...
- ora00972标识符过长
oracle10G对于表名的长度限制是30个字节 表名超过30结果不能创建,提示ora00972-标识符过长. 需要将表名控制在30个字节以内
- time() 函数时间不同步问题
1.时区设置问题 处理方法:编辑php.ini 搜索 “timezone” 改写为 PRC 时区 2.服务器时间不同步 处理方法:设置服务器时间和本地时间进行同步
- Python senium 中页面属性
1.通过id定位元素2.通过class_name定位元素3.通过tag_name定位元素4.通过name定位元素5.通过link文字精确定位元素6.通过link文字模糊定位元素7.通过CSS定位元素8 ...
- python — 索引与pymysql模块
1. 索引 1.1 索引原理 1.什么是索引 ?-- 目录 索引就是建立起的一个在存储表阶段就有的一个存储结构,能在查询的时候加速. 2.索引的重要性: 读写比例 为 10:1,所有读(查询)的速度就 ...
- MySQL Sakila示例数据库
Table of Contents 1 Preface and Legal Notices 2 Introduction 3 History 4 Installation 5 Structure ...