Skip to content

new的原理是什么?通过new的方式创建对象和通过字面量创建有什么区别? #55

Open
@TieMuZhen

Description

@TieMuZhen

new 的过程

new关键字会进行如下的操作:

  1. 创建一个空的简单JavaScript对象(即{});
  2. 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象prototype
  3. this指向步骤1新创建的对象 ;
  4. 如果该函数没有返回对象,则返回this

示例讲解

以下面代码为例讲解

function Animal (name) {
  this.name = name;
}
var cat = new Animal('dog');

var cat = new Animal('dog');是关键代码,js引擎在执行这句代码的时候,内部做了很多工作,用伪代码模拟一下其内部流程如下:

new Animal('dog') 相当于 {
  var obj = {};
  obj.__proto__ = Animal.prototype;
  var result = Animal.call(obj, 'dog');
  return typeof result === 'object' ? result : obj;
}

解析上述步骤:

1、新生成一个对象:创建一个空对象obj

2、链接到原型:把obj__proto__指向了构造函数的Animal的原型对象prototype

3、绑定this.callapplybind:在obj对象的执行环境中调用Animal函数并传递参数dog,相当于var result = obj.Animal('dog'),当执行完这句话后obj就产生了属性name并赋值“dog”

4、返回新对象(如果构造函数有自己的return,则返回该值):观察第三步的返回值,如果无返回值或者返回一个非对象值,则将obj作为新对象返回,否则会将result作为新对象返回。

实现一个简单的new方法

function _new() {
    let target = {}; //创建的新对象
    //第一个参数是构造函数
    let [constructor, ...args] = [...arguments];
    //执行[[原型]]连接;target 是 constructor 的实例
    target.__proto__ = constructor.prototype;
    //执行构造函数,将属性或方法添加到创建的空对象上
    let result = constructor.apply(target, args);
    if (result && (typeof (result) == "object" || typeof (result) == "function")) {
        //如果构造函数执行的结构返回的是一个对象,那么返回这个对象
        return result;
    }
    //如果构造函数返回的不是一个对象,返回创建的新对象
    return target;
}

测试写的_new方法

function Person(name) {
    this.name = name;
};
Person.prototype.sayName = function () {
    console.log(this.name);
};
const p = _new(Person, 'Tom');
p.sayName(); // Tom

创建对象的方法和区别

创建对象的三种方法

  • 字面量(var obj = {}
  • new构造器
  • Object.create()

三种方法的区别

new和Object.create()区别

  • new出的实例继承构造函数的属性,Object.create()出的实例不继承构造函数的属性,Object.create(arg, pro)创建的对象的原型取决于argargnull,新对象是空对象,没有原型,不继承任何对象;arg为指定对象,新对象的原型指向指定对象,继承指定对象

对象字面量和Object.create区别

  • 对象字面量不会调用Object构造函数, 简洁且性能更好;
  • 对象字面量是纯对象,Object.create是实例对象
  • 对象字面量原型指向ObjectObject.create(arg, pro)原型取决于arg
  • 对象字面量属性是非继承属性,Object.create()出的实例不继承构造函数的属性

参考文献

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions