new操作符干了什么?

我们可以一起通过代码实现来看看new关键字到底做了一些什么事情

function Book(name) {
    this.name = name;
}
Book.prototype.say = function() {
    console.log(this.name);
};
let book = new Book('javascript高级程序设计');
console.log(book);
book.say();

输出结果如下图:


new操作符实例化构造函数

上例中,new关键字调用的构造函数并没有任何返回值,最终我们实例创建了一个对象,那如果构造函数拥有返回值呢?new关键字会如何处理

function Test(name) {
    this.conname = name;
    return 1
}
Test.prototype.say = function() {
    console.log(this.conname);
};
let test = new Test('测试');
console.log(test);
test.say();
new操作符对于拥有返回值的构造函数

上例中,构造函数返回了一个基本数据类型的值,而最终我们依旧拿到了想要的实例对象。那如果构造函数返回一个引用类型的值呢?

function Test(name) {
    this.conname = name;
    return {
        name
    }
}
Test.prototype.say = function() {
    console.log(this.conname);
};
let test = new Test('测试');
console.log(test);
test.say();

上例中,构造函数最终返回了一个对象,这个对象上有name属性,然后在构造函数的prototype上,还拥有say方法,我们看看这次new得到的值是什么,是否拥有构造函数prototype上的方法


new操作符对于拥有返回值的构造函数

可以看到的是,我们拿到的对象是最终构造函数return出来的那个对象,而这个对象并没有构造函数prototype上的say方法

经过测试,我们发现

  1. new关键字 通过构造函数创建出来的实例可以访问到构造函数中的属性
  2. new关键字 通过构造函数创建出来的实例可以访问到构造函数原型链中的属性,也就是说通过 new 操作符,实例与构造函数通过原型链连接了起来
  3. new关键字 操作的构造函数如果返回基本类型,那么这个返回值毫无意义
  4. new关键字 操作的构造函数如果返回引用类型,那么这个返回值会被正常使用

通过上述的一些测试,我们可以自己试着实现一下new关键字;

function Book(name) {
    this.name = name;
}
Book.prototype.say = function() {
    console.log(this.name);
};
function myNew(Constructor, ...args) {
    let obj = {};
    obj.__proto__ = Constructor.prototype;
    let result = Constructor.call(obj, ...args);
    return result instanceof Object ? result : obj;
}
let book = myNew(Book, 'javascript高级程序设计');
console.log(book);
book.say();
自己实现new关键字
总结 new关键字到底做了些什么
  1. 先创建了一个新的空对象
  2. 然后让这个空对象的proto指向函数的原型prototype
  3. 将对象作为函数的this传进去,如果return 出来东西是对象的话就直接返回 return 的内容,没有的话就返回创建的这个对象

你可能感兴趣的:(new操作符干了什么?)