一篇就够-JS的new实现

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;
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,877评论 0 3
  • 第一章 错误处理: 错误: 程序运行过程中,导致程序无法正常执行的现象(即bug) 现象: 程序一旦出错,默认会报...
    fastwe阅读 1,256评论 0 1
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,538评论 3 12
  • JavaScript面向对象程序设计 本文会碰到的知识点:原型、原型链、函数对象、普通对象、继承 读完本文,可以学...
    moyi_gg阅读 841评论 0 2
  • 早上带以恒吃粥,他故意把头靠在宝宝椅上说不饿。我知道他这是想看小黄鸭的伎俩,(小黄鸭相当于一个小电脑,里面什么都有...
    汾湖草木人阅读 411评论 6 5

友情链接更多精彩内容