new的作用
function Fruit(name){
this.name = name;
}
Fruit.prototype.show = function(){
console.log(this.name);
}
var banana = new Fruit('banana');
//输出Fruit.protoype
console.log(Object.getPrototypeOf(banana));
//输出Fruit.prototype
console.log(banana.__proto__);
//输出'banana'
console.log(banana.show());
//输出'banana'
console.log(banana.name);
//输出true
console.log(banana.hasOwnProperty("name"));
//输出false
console.log(banana.hasOwnProperty("show"));
可以看到,经过new之后返回了一个对象,该对象的构造函数原型为Fruit.prototype,也就是proto指向Fruit.prototype
并且banana可以调用show和name属性,但name是其拥有的属性,show是原型上的属性。
也就是new做了以下几件事
- 返回一个对象,该对象的proto指向构造函数的原型
- 该对象会实现构造函数中的实例属性,也就是调用构造函数的apply方法
初步实现new操作符
function objectFactory(paramConstrutor){
if(typeof paramConstrutor !== 'function' ){
throw new Error("");
}
var args = Array.prototype.slice.call(arguments,1);
//设置obj的proto为constructor的proto,也就是继承共享属性
//两种方式,
//一种是直接设置__proto__,官方不建议,后面可能变成只读属性
var obj = new Object();
obj.__proto__ = paramConstrutor.prototype;
//一种是通过Object.create()或者该方式的polyfill
//模拟Object.create()
function Empty(){};
Empty.prototype = paramConstructor.prototype;
var obj = new Empty();
//继承实例属性
paramConstructor.apply(obj,args);
return obj;
}
如果构造函数由返回值,那应该是返回新建的对象还是返回值呢?
- 直接返回返回值,当返回值是Object、Function、Array、Date、RegExg、Error
- 返回新建对象,当返回值是Null、Undefined、Number、Boolean、String、Symbol
function Fruit(name){
this.name = name;
return {
a:1
}
}
var banana = new Fruit('banana');
//{a:1}
console.log(banana);
function Fruit(name){
this.name = name;
return 1;
}
var banana = new Fruit('banana');
//Fruit {name:'banana‘}
console.log(banana);
完整代码
根据上面的返回值,进一步完善代码。
需要了解的:
- typeof检测除了Function之外的都为object
- typeof检测Null为object
function objectFactory(paramConstructor){
if(typeof paramConstructor !== 'function'){
throw new Error("");
}
var args = Array.prototype.slice.call(arguments,1);
//继承共享属性,修改proto属性
function Empty(){};
Empty.prototype = paramConstructor.prototype;
var obj = new Empty();
//继承实例属性
var result = paramConstructor.apply(obj,args);
var isObejct = typeof result === 'object' && result !== null;
var isFunction = typeof result === 'function';
if(isObejct ||isFunction ){
return result
}
return obj;
}
网友评论