zoukankan      html  css  js  c++  java
  • 模拟new实例化对象。

    使用new和字面量的的方法是两种主流创建对象的方法,两种最终都能达到同样的实例化的对象,本章主要围绕new关键字来实例化一个对象并且讲一个不使用new但是完全与new实例化对象相同的例子。

    在使用new后面跟一个构造函数的时候,将会返回一个新对象,

    这个对象中的属性便就是new后面跟的构造函数中的this的属性

    这个对象的__proto__属性指向就是new后面的构造函数的prototype属性。

    prototype属性的值是一个对象,是Javascript为每一个函数内置的一个属性,也就是说,所有的函数都能成为构造函数,所以不到万不得已不要覆盖原来的值,更加不要使用基本类型覆盖prototype属性。

    new可以总结为下面几个步骤:

    1. 创建一个新对象
    2. 把这个新对象的__proto__指向构造函数的prototype属性
    3. 把构造函数中的this上的属性全部添加到新对象
    4. 返回这个新对象

    通过这四个步骤,返回了一个新实例化对象,牢记这四个步骤,就能轻松的模拟出new的效果,或者通过new模拟字面量的表示法。

    假设现在有一个构造函数

    //构造函数首字母大写并不是强烈要求,只是一种书写的规范
    function Fun(){
        this.a = 1;
        this.b = "字符串";
        this.arr = [1,2]
    }
    //每个函数中都内置了一个prototype属性
    //可以通过console.log(Fun.prototype)打印出来看看
    Fun.prototype.c = "prototype"
    //不要直接覆盖prototype,就像下面这个例子 // Fun.prototype = "obj" //但是如果非要覆盖的话,你可以这样做 // Fun.prototype = { // constructor:Fun // 把constructor属性指回构造函数 // 可以达到一样的效果 // }

    执行上面的代码,接下来只需要 new Fun() 就可以返回一个新对象,并且这个对象里面拥有a,b,arr的属性,原型链__proto__上拥有c这个属性,它的结构是这样的

     1 //一些只是表示结构。不能执行
     2 Fun {
     3 
     4     a:1,
     5     b:"字符串",
     6     arr:[1,2]
     7     __proto__:{
     8         c : "prototype",
     9         constructor:function Fun()
    10         __proto__: ......
    11     }
    12 }

    但是,这并不是目的,目的是希望不通过new来得到一个新对象并且跟new出来一样的结果。

    首先执行第一步(返回一个新对象):

    1 //通过字面量创建一个新对象 
    2  var obj = {} 

    得到这个对象之后把这个对象的__proto__指向prototype

    //这里__proto__与prototype的值都是对象
    //最终对象的原型链都将指向一个带get,set方法的超级对象
    //__proto__是对象的原型链属性
    //prototype是构造函数的一个属性
    obj.__proto__ = Fun.prototype

    然后需要把构造函数中this的属性全部拷贝到对象的中,这时可以使用call或在apply方法。

    1 //把obj作为第一个参数传入到call中
    2 //这是Fun中的this就变成了obj
    3 //Fun通过call执行之后,this中的属性就被拷贝到了obj中
    4 Fun.call(obj)
    5 //或在Fun.apply(obj)
    6 //两个方法仅有的区别就是所传的参数不同。

    最后打印一下obj,发现它与new出来的对象几乎没有差异

    以下是完整代码

    function Fun(){
         this.a = 1;
         this.b = "字符串";
         this.arr = [1,2]
     }
    Fun.prototype.c = "prototype";
    var obj = {};
    obj.__proto__ = Fun.prototype;
    Fun.call(obj)
    var newObj = new Fun();
    console.log(obj);
    console.log(newObj);
  • 相关阅读:
    如何让自己拥有两年工作经验
    示波器入门使用方法
    模板显式、隐式实例化和(偏)特化、具体化的详细分析
    Dynamics CRM 2013 初体验(5):Business Rule
    Tomcat搭建
    岁月,时光,现实
    数据结构之链表单向操作总结
    iptables学习笔记
    知无涯者(The Man Who Knew Infinity)
    Dynamics CRM2016 Web API之Expand related entities & $ref & $count
  • 原文地址:https://www.cnblogs.com/Amy-so/p/5529398.html
Copyright © 2011-2022 走看看