为啥要用new: 在javascript中, 经过new能够产生原对象的一个实例对象,而这个实例对象继承了原对象的属性和方法。javascript
new操做符干了什么:java
new的过程当中遇到的坑一:bash
new Function
返回的是一个函数,
new Object
返回的是一个对象,那么什么是普通对象什么是函数对象?
经过查找资料发现有这么一句话:凡是经过 new Function()
建立的对象都是函数对象,其余的都是普通对象。闭包
new的过程当中遇到的坑二:app
咱们看到new一个普通对象报错,new一个函数对象才能够,对于这个结果很好奇为何?因而又查资料。函数
原型对象:ui
1).显式原型: 每一个函数对象都有prototype属性,称为显式原型
2).隐式原型: 每一个普通对象都有_proto_属性,指向的是相对应的构造函数的prototype,称为隐式原型
复制代码
是否是能够这么理解,new一个普通对象,由于只有函数对象才有prototype
属性,因此普通对象没法通new来建立一个新对象。只有经过函数对象来用new建立一个新的普通对象。this
分析上面步骤的具体内容:spa
__proto__
属性,普通对象的__proto__
属性指向他的构造函数(函数对象)的prototype
,因此a是b的构造函数,b是a的实例对象。具体实现步骤:prototype
function _new (fn) {
var obj = {
__proto__ : fn.prototype,
};
var res = fn.call(obj);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
复制代码
咱们来运行一下代码:
var o3 = new fun ('tom');
,并且若是构造函数包含好几个属性,在new的过程当中,有可能会传入多个参数。 咱们须要改造一下:
function _new (fn) {
return function () { // 返回一个函数,调用此函数时传入的参数达到new带参数的目的。
var obj = {
__proto__ : fn.prototype,
};
var res = fn.apply(obj, arguments);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
}
复制代码
咱们再来运行一下代码:
固然使用闭包的方式会有内存泄漏的风险!因此咱们还能够改造一下:
function _new () {
var fn = [].shift.call(arguments);
//var ags = [].prototype.slice.call(arguments, 1);
var obj = {
__proto__ : fn.prototype,
};
var res = fn.apply(obj, arguments);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
复制代码