Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
TieMuZhen opened this issue Nov 30, 2021 · 0 comments

Comments

@TieMuZhen
Copy link
Owner

TieMuZhen commented Nov 30, 2021

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()出的实例不继承构造函数的属性

参考文献

@TieMuZhen TieMuZhen changed the title new运算符的执行过程 new的原理是什么?通过new的方式创建对象和通过字面量创建有什么区别? Dec 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant