1.前言

众所周知:没有对象怎么办?那就new一个!

那么在JS中,当我们new一个对象的时候,这个new关键字内部都干了什么呢?

现在我们就来剖析一下原生JS中new关键字内部的工作原理。

2.原生的new

首先,我们先new一个对象看看:

//创建Person构造函数,参数为name,age
function Person(name,age){
  this.name = name;
  this.age = age;
 }
//实例化对象小明
xm = new Person('xiaoming',18);
//打印实例化出来的对象小明
console.log(xm);

打印结果:

从打印结果中可以看到:

用new关键字实例化对象时,首先创建了一个空对象xm,并且这个空对象包含两个属性name和age,分别对应构造函数中的两个属性,其次我们也可以知道实例化出来的这个对象xm是继承自Person.prototype。

3.new 命令的原理

了解了以上过程,那么现在我们就可以总结出new关键字在实例化对象时内部都干了什么,其实,new关键字内部干了如下四件事:

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 执行构造函数,并将这个空对象赋值给函数内部的this关键字。
  4. 判断构造函数的返回值,如果是对象则返回这个对象,否则返回新创建的对象。

也就是说,构造函数内部,this指的是一个新生成的空对象,所有针对this的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this对象),将其“构造”为需要的样子。

如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。

4.封装_new函数

当我们知道new关键字的内部原理后,我们就可以封装一个_new函数,使其用于与new关键字同样的功能。

_new函数需要传入以下几个参数:

第一个参数:构造函数名Func;

第二个参数及后面的参数:构造函数的参数

function _new(){
  //1.拿到传入的参数中的第一个参数,即构造函数名Func
  var Func = [].shift.call(arguments);
  //2.创建一个空对象obj,并让其继承Func.prototype
  var obj = Object.create(Func.prototype);
  //3.执行构造函数,并将this指向创建的空对象obj
  var result = Func.apply(obj,arguments)
  //4.如果构造函数返回结果是对象,就直接返回,否则返回创建的对象obj
return (typeof result === 'object' && result != null) ? result : obj;
}

5.测试

封装好后,我们来测试一下封装的_new函数,看看它是否实现了和原生new关键字同样的功能。

//创建Person构造函数,参数为name,age
function Person(name,age){
  this.name = name;
  this.age = age;
} function _new(){
  //1.拿到传入的参数中的第一个参数,即构造函数名Func
  var Func = [].shift.call(arguments);
  //2.创建一个空对象obj,并让其继承Func.prototype
  var obj = Object.create(Func.prototype);
  //3.执行构造函数,并将this指向创建的空对象obj
  var result = Func.apply(obj,arguments)
  //4.如果构造函数返回结果是对象,就直接返回,否则返回创建的对象obj
return (typeof result === 'object' && result != null) ? result : obj;
} xm = _new(Person,'xiaoming',18); console.log(xm);

测试结果:

从测试结果看到,_new函数的功能与new关键字完全一致。

(完)

原生JS封装_new函数,实现new关键字的功能的更多相关文章

  1. 原生JS封装创建多级菜单函数

    手写一个使用原生JS封装的多级菜单的函数,满足以下几点需求. 子类层级不确定,可根据数据自动生成多级菜单. 操作便捷,只需传入一个HTML标签. 缺点: 需要满足特定的数据结构 废话不多说,展示代码. ...

  2. 使用原生JS封装一个动画函数

    最近一直在忙项目,很少有时间回顾之前的知识,今天刚好要做一个轮播,因为对兼容性有一定的要求,使用了各种插件和库中的轮播,效果都不是很理想,一怒之下,使用原生JS封装了一个轮播组件,其中重要的功能就是一 ...

  3. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  4. 用jQuery基于原生js封装的轮播

    我发现轮播在很多网站里面都用到过,一个绚丽的轮播可以为网页增色不少,最近闲来无事,也用原生js封装了一个轮播,可能不像网上的插件那么炫,但是也有用心去做.主要用了闭包的思想.需要传递的参数有:图片地址 ...

  5. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  6. 基于原生JS封装数组原型上的sort方法

    基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...

  7. 用原生js封装轮播图

    原生js封装轮播图 对于初学js的同学来说,轮播图还是一个难点,尤其是原生js封装轮播图代码,下面是我之前做的一个轮播图项目中封装好的一些代码,有需要的同学可以看一下,有什么不懂的可以看注释,注释看不 ...

  8. 原生JS封装简单动画效果

    原生JS封装简单动画效果 一致使用各种插件,有时候对原生JS陌生了起来,所以决定封装一个简单动画效果,熟悉JS原生代码 function animate(obj, target,num){ if(ob ...

  9. 原生Js封装的弹出框-弹出窗口-页面居中-多状态可选

    原生Js封装的弹出框-弹出窗口-页面居中-多状态可选   实现了一下功能: 1.title可自定义 可拖拽 2.width height可以自定义 3.背景遮罩和透明度可以自定义 4.可以自己编辑弹出 ...

随机推荐

  1. Vue入门教程 第三篇 (条件与循环)

    v-if语法(条件) 符合条件时显示(渲染)某一元素. <div id="app"> <div v-if="ok"> <h1> ...

  2. python编程基础之十二

    列表:一种有序的集合,可以同时存储多个数据,列表元素可修改,属于可变序列 创建列表: 列表名 = [列表选项一,列表选项二,列表选项三,......] list1 = [] list2 = [10,2 ...

  3. 编程杂谈——使用emplace_back取代push_back

    近日在YouTube视频上看到关于vector中emplace_back与push_back区别的介绍,深感自己在现代C++中还是有不少遗漏的知识点,遂写了段代码,尝试比较两者的差别. 示例代码 #i ...

  4. bugku旋转跳跃

    下载下是一个mp3音频,尝试听了下,没有收获, 使用mp3stege,将文件拷在mp3stege目录下,然后使用cmd cd到目录下 命令行是decode -X -P 密码 文件 生成了一个文本 打开 ...

  5. [书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers

    本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解Ja ...

  6. 手把手教你搭建HEXO免费博客

    一.环境搭建 node安装 百度搜索node,进入官网.下载稳定版: 下载好后直接打开安装 我这里将其安装在D盘(可以自己选择安装位置) 可以看到安装包中已经自带npm包管理工具 等待安装完成后,WI ...

  7. 03jmeter-json提取器

    要解决的问题:接口返回数据为json格式,需要获取返回结果中的某些值以便后续接口使用 注:可用json path tester(https://jsonpath.curiousconcept.com/ ...

  8. 2.单核CPU是如何实现多进程的?

    单核cpu之所以能够实现多进程,主要是依靠于操作系统的进程的调度算法 如时间片轮转算法,在早期,举例说明:有5个正在运行的程序(即5个进程) :   QQ    微信    有道词典      网易云 ...

  9. Arduino学习笔记③ 经典LED

    1.前言     今天我们开始同时讲解理论以及实践.对于绝大部分有过单片机编程经历的人来说,第一个接触的大多数就是LED灯(忽然想起博主大一那个懵懂的时代,当时大三的师兄给我们展现了一把流水灯功力,当 ...

  10. vue系列文章 --- 源码目录结构整理(三)

    vue的版本是:^2.6.10 结构如下: |----- vue | |--- dist # 打包之后的目录vue文件 | | |--- vue.common.dev.js | | |--- vue. ...