原型与原型链

构造函数

所谓构造函数,其实就是一个普通函数,但是内部使用了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

posted @ 2019-09-18 09:26  windalm  阅读(177)  评论(0编辑  收藏  举报