详细深入new 一个对象时的细节过程
new一个对象的过程:
- 会创造一个对象(obj)
- 会将构造函数的this指向创造出来的对象(obj)
- obj.proto = 构造函数.prototype
- 返回值:
- 一般是创造的那个对象obj,但是如果构造函数的返回值是一个引用类型的值,那么返回的就是那个引用类型(改变了返回值)
- 如果构造函数的返回值是一个基本类型值 或者没有写,那么返回值还是一个obj(没有改变)
实现_new()函数:
function _new(callback,...params){
let obj = {
};//创造出一个对象
let returnValue = callback.call(obj,...params);//调用callback时,改变callback时中的this为obj
obj.__proto__ = callback.prototype;
if (/(object|function)/.test(typeof returnValue)){
return returnValue;
}else {
return obj;
}
}
function sme(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
}
let pp = _new(sme,"李华","男","18")
console.log(pp.name);//李华
IE9以下的不兼容__proto__,如何兼容IE9以下
1.我们可以使用Object.create(sme),当我们使用Object.create()是发生了什么
1.1:会返回一个新的对象,而这个对象的__proto__指向sme
function _new(callback,...params){
let obj = Object.create(callback.prototype);//但是没有获得callback的私有属性,Object.create()的参数要是一个对象,所以才用callback.prototype
//1.现在创建一个新对象(obj),而且obj.__proto__ = callback.prototype
let returnValue = callback.call(obj,...params); //获取返回值,根据返回值进行判断
if (/^(object|function)$/.test(typeof returnValue)){
return returnValue
}else {
return obj
}
}
但是Object.create对象IE低版本还是不兼容
解决办法
function _new(callback,...params){
let obj = newObject(callback.prototype);
let returnValue = callback.call(obj,...params);
if (/^(object|function)$/.test(returnValue)){
return returnValue
}else {
return obj;
}
}
function newObject(obj) {
function proxy(){
}
proxy.prototype = obj
return new proxy()
}