深入理解JavaScript之 new 原理及模拟实现

更新日期: 2019-12-24阅读: 1.9k标签: new

1.定义

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例

先看看 new 实现了哪些功能, 先来看一段代码

function Person(age) {
    this.age = age;
}
Person.prototype.getAge = function() {
    console.log("年龄为:" + this.age );
}

var person = new Person(18);
person.age; // 访问构造函数里的属性
// 18

person.getAge(); // 访问原型里的属性
// 年龄为:18

从上面代码可以知道,实例 person 可以:

  1. 访问到 Person 构造函数里的属性
  2. 访问到 Person.prototype 中的属性

这个是最基本的了,也是刚学会new一个对象就知道这是new的特点


2.探讨new还做了什么?

探讨完上面,接下来看看new还做了什么?来看几个例子

1. 没有return语句

function Person(age) {
    this.age = age;
}

var person = new Person(18);
console.log(person); // Person {age: 18}

从构造函数直观看,最后是没有 return语句的,但我们从返回结果也可以看出构造函数时默认情况会返回一个新对象

2. return 对象数据类型

我们尝试在构造函数最后返回一个对象

function Person(age) {
    this.age = age;
    return { name: '手动返回一个对象' }
}

var person = new Person(18);
console.log(person); // {name: "手动返回一个对象"}

打印出来的结果可以看书:return 之前的代码片段都被覆盖了,最后返回 return 后面的对象。

3. return 基本数据类型

如果构造函数最后return的不是对象呢,试下基本数据类型

function Person(age) {
    this.age = age;
    return 1 
}

var person = new Person(18);
console.log(person); // Person {age: 18}

从打印出来的结果可知,和没有return效果一样。


3.new原理

mdn上把内部操作大概分为4步:

  1. 创建一个空的简单JavaScript对象(即{ } );
  2. 链接该对象(即设置该对象的构造函数)到另一个对象 ;(因此this就指向了这个新对象)
  3. 执行构造函数中的代码(为这个新对象添加属性);
  4. 如果该函数没有返回对象,则返回this。


5.模拟实现new

new 是关键词,不可以直接覆盖。这里使用 create 来模拟实现 new 的效果。

function myNew() {
    // 创建一个空的对象
    var obj = new Object(),
    // 获得构造函数,arguments中去除第一个参数
    Con = [].shift.call(arguments);
    // 链接到原型,obj 可以访问到构造函数原型中的属性
    obj.__proto__ = Con.prototype;
    // 绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 优先返回构造函数返回的对象
    return ret instanceof Object ? ret : obj;
};

来看看上面是怎么一步步模拟实现的:

  1. 用new Object() 的方式新建了一个空对象 obj
  2. 取出第一个参数,即是传入的构造函数。shift 会修改原数组,数组原来的第一个元素的值。
  3. 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性
  4. 使用 apply,改变构造函数 this 的指向。将this指向obj对象 就可以访问到构造函数中的属性
  5. 处理返回值。
  • 构造函数返回值有三种情况:
  1. 没有return,默认返回之前创建的对象
  2. 返回一个对象
  3. 返回的不是对象,默认返回之前创建的空对象

在上面我们用instanceof方法来判断是否为对象

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

测试:

function Person(age) {
    this.age = age;
}
Person.prototype.getAge = function() {
    console.log("年龄为:" + this.age );
}

var person = create(Person, 18)
person.age; // 访问构造函数里的属性
// 18

person.getAge(); // 访问原型里的属性
// 年龄为:18

模拟实现成功!


链接: https://fly63.com/article/detial/7598

new.target属性_你可能不知道的 new.target

new 是构造函数生成实例的命令, ES6为 new 命令引入了 new.target属性。这个属性用于确定构造函数是怎么调用的。在构造函数中, 如果一个构造函数不是通过 new操作符调用的, new.target会返回 undefined。

new 操作符 做了什么?

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。假设Test是一个构造函数,通常在创建对象的实例时,要使用new,eg:test = new Test() , 那么在调用new的时候,发生了什么呢?

JS中的new操作符原理解析

1. 创建一个类的实例:创建一个空对象obj,然后把这个空对象的__proto__设置为Person.prototype(即构造函数的prototype);2. 初始化实例:构造函数Person被传入参数并调用,关键字this被设定指向该实例obj;3. 返回实例obj。

JS深度解析 new 原理及模拟实现

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 ——(来自于MDN)new 创建的实例有以下 2 个特性:1、访问到构造函数里的属性;2、访问到原型里的属性

“写”一个js的new运算符

new 运算符 创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。比较好奇new运算符的原理,了解了下,分享给大家。自己写一个New()方法,

JS中new操作符源码实现

首先我们来看一下实例化一个对象做了浏览器做了什么事情,new的四步操作:1. 创建一个空对象2. 设置空对象的__proto__属性继承构造函数的prototype属性,也就是继承构造函数的原型对象上的公有属性和方法

你知道多少this,new,bind,call,apply?

那么什么是this,new,bind,call,apply呢?这些你都用过吗?掌握这些内容都是基础中的基础了。如果你不了解,那还不赶快去复习复习,上网查阅资料啥的!通过call,apply,bind可以改变this的指向

Js中new操作符的详细过程

理解new对象过程,需要提前了解原型及原型链的相关知识;我们都知道,JS当中创建对象使用的是原型设计模式,即使用new操作符调用构造函数,这里先看一个例子:

js之new的原理

对于创建一个对象来说,更推荐使用字面量的方式创建对象(无论性能上还是可读性)。因为你使用 new Object() 的方式创建对象需要通过作用域链一层层找到 Object

JS中NEW的实现原理及重写

上面的代码,我们首先创建了一个函数,如果是用面向对象的说法就是创建了一个Function类的实例,如果直接执行这个函数,那它就是一个普通的函数,如果用new执行,则这个函数被称为一个自定义的类。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!