zoukankan      html  css  js  c++  java
  • 原型与原型链

    构造函数

    所谓构造函数,其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。构造函数始终应该以一个大写字母开头,非构造函数应该以一个小写字母开头

    function Person(name, age, job){
                this.name = name;
                this.age = age;
                this.job = job;
                this.sayName = function(){
                    alert(this.name);
                };    
            }
    

    原型

    让某一大类都具有共同的方法

    Person.prototype.sayName = function(){
                alert(this.name);
            };
    

    对象实例进阶

    指针的概念:当我们定一个变量的时候,会在内存中开辟一段区域保存这个变量的值,每个内存区域都有一个对应的地址,我们一般都是通过地址找到这个值的。类似门牌号 。

    对象时如何在内存中存储的:在内存中开辟两段区域,一段区域存储变量名称(地址),一段区域才是存储实例真正的值。

    var product = new product();
    

    product变量中保存的只是地址,具体的内容放在另一块区域里面。

    对象拷贝理论

    • 实例化的过程其实就是拷贝构造函数所有属性(包含定义的也包含隐藏的)的过程
    • 除了拷贝以外还会自动生成一个constructor属性,用于识别其是根据哪个构造函数创建的实例
    • 每当我们实例化的时候,都会将构造函数的属性拷贝一份,同时赋给新值,就给将内存空间替换掉。
    • constructor:构造函数隐藏的一个属性。

    原型的属性(方法)共享理论

    原型对象不管实例化多少次,都只会生成一次。

    • 只用构造函数创建对象存在的缺点
      • 对象需要实例化
      • 每次实例化都要分配内存存储这些数据
      • 如果实例很多,那就要分配很多内存存储
      • 一般每个实例的属性是不一样的,而行为一般都是一样的,所以我们希望实例化的时候,只分配内存保存不一样的数据。
      • 而像方法,可以只分配一次空间,所有的实例共享这些方法,那就需要原型对象。
    • 原型对象只分配一次内存
    • 实例化的时候只拷贝构造函数中的属性,而不会拷贝原型对象中的属性。
    • 原型对象的本质:
      • 原型对象的属性和方法可以被所有实例共享
      • 这样,如果我们修改所有实例中的属性或者方法,就只需要修改移除,就能够影响所有实例了。

    函数搜索机制

    本质:通过prototype属性中保存的地址链接原型

    • 先在自己的属性列表中寻找,如果找到直接返回,如果找不到从原型中寻找。如果找不到,先找到自身的一个隐藏属性prototype,这个属性中保存的是原型对象的地址。

    • 任何一个我们编写的函数其实都是Function对象,既然对象是函数实现的,那么对象也是Function的一个实例,所以构造函数含有Function对象中的一切属性和方法。而constructor属性,prototype属性是Function对象中的属性之一,而实例化的时候会拷贝构造函数中的属性和方法,自然就有了constructor属性和prototype属性。

    • prototype属性--保存的就是地址。

    • 作用:将实例和原型对象联系在一起

    双对象法则

    • 构造函数对象
    • 原型对象
    • 通过属性-proto-联系在一起
    • 实例化的时候,实例首先拷贝构造函数的所有属性,先在自己的属性列表中寻找,如果找不到,先找到自身的一个隐藏属性prototype,这个属性中保存的是原型对象的地址。

    1565698656814

    1565698684802

    prototype、proto和constructor的三角关系

    1565699077958

    function Foo(name, age, job){
                this.name = name;
                this.age = age;
                this.job = job;     
    };
    
    Foo.prototype.sayName = function(){
                alert(this.name);
    };
    var f1 = new Foo;
    
    //__proto__属性指向实例的原型对象
    console.log(f1.__proto__ === Foo.prototype)//true
    //constructor属性指向创建它的构造函数
    console.log(f1.constructor === Foo);//true
    console.log(Foo.prototype.constructor === Foo);//true
    

    参考:https://www.cnblogs.com/xiaohuochai/p/5721552.html

    1565954699747

  • 相关阅读:
    C#语法造成的小问题(编译原理知识)
    COM套间对.NET程序使用COM对象的影响
    为什么连接字符串一定要用StringBuilder(介绍CLR Profiler)
    编译原理系列文章
    .NET与COM互操作系列
    Windows XP SidebySide功能对VC程序的影响
    引起FileNotFoundException原因通用分析过程
    Flex组件的项目渲染器(ItemRenderer)使用总结
    Flex组件开发总结20090209
    如何去掉超链接图片外蓝色的边框
  • 原文地址:https://www.cnblogs.com/zhoujingguoguo/p/11539650.html
Copyright © 2011-2022 走看看