new一个函数的时候发生了什么

var Fn = {}

var fn = new Fn()

这个过程会执行如下步骤:

1.新创建一个空对象

var fn = new Object();

2.构造函数的显示原型等于实例对象的隐式原型,实例对象的constructor属性为构造函数的名称

Fn.prototype = fn.__proto__

3.通过调用call、apply方法执行构造函数并改变this对象(绑定到实例对象上)

Fn.call(f)

4.如果没有手动返回其他任何对象或返回值是基本类型(Number、String、Boolean)的值,会返回 this 指向的新对象,也就是实例,若返回值是引用类型(Object、Array、Function)的值,则实际返回值为这个引用类型。

var New =function(fn){
        //1.新建空对象
        var obj={};
        //2.实例对象的__proto__等于构造函数的prototype
        obj.__proto__=fn.prototype;
        //3. 将 arguments 对象转为数组
        var args = [].slice.call(arguments);
        //4.去除构造函数
        args.shift();
        //5. 通过调用call、apply方法执行构造函数并改变this对象
        var result = fn.apply(obj, args);
        //6. 判断返回值,如果是Object类型就直接返回,否则返回实例对象本身
        if(Object.prototype.toString.call(result)=="[object Object]" ){
            return result
        }else{
            return obj;
        }
    }
    var Fun=function(sex){
        this.name='hty';
        this.sex=sex;
    }
    const fun=New(Fun,'123');
    console.log(fun.name);//hty
    console.log(fun.sex);//123

自己手写实现一个简单的new

function myNew (fun) {
        return function () {
            // 创建一个新对象且将其隐式原型指向构造函数原型
            let obj = {
                __proto__ : fun.prototype
            }
            // 执行构造函数
            fun.call(obj, ...arguments)
            // 返回该对象
            return obj
        }
    }

    function person(name, age) {
        this.name = name
        this.age = age
    }
    let obj = myNew(person)('li', 18)
console.log(obj)

注意:

箭头函数中没有 [[Construct]] 方法,不能使用 new 调用,会报错。除了箭头函数之外的任何函数都可以new。

自己模拟面试想到的面试题

构造函数怎么调用的?(new)

为什么要用new来调用,而不是直接调用?

用new调用的时候,会新建一个空的实例对象,将构造函数的显示原型等于实例的隐式原型,会将构造函数原型上的属性和方法都继承到实例对象中,会将this指向这个新实例对象,如果不用new调用的话就相当于是一个普通函数,this会指向window,也无法继承构造函数的任何属性。

想要系统了解更多知识推荐这个:https://www.cnblogs.com/echolun/p/10110839.html

https://developer.51cto.com/art/201807/578260.htm

Object.prototype.toString()

返回一个表示该对象的字符串

可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString

不积跬步无以至千里
原文地址:https://www.cnblogs.com/lyt0207/p/12365563.html