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