javascript之原型(prototype)

一、由来

  1. 当初在设计javascript时不想引入类的概念,但要实现类的功能。借鉴了高级面向对象语言中,创建一个实例时,其实就是执行了该类的构造函数,因此,作者用   new + 构造函数  的形式来表示生成的实例。这里提到的构造函数其实就是我们平时常见到的普通函数,只是为了区分,首字母大写。
  2. 还有一个问题:这样创建出来的实例,来自同一个“类”,但却不知道,这时提出了prototype的概念,用来存放该实例的构造函数。
  3. 除了通过bind绑定的没有,每个函数都有prototype属性,prototype属性包含了contructor和在构造函数中定义的所有属性和方法。其中,contructor是真正存放该实例的构造函数的地方。

二、与constructor的关系

  其实真正存放实例的构造函数是在constructor,constructor指向构造函数,constructor又是prototype的属性,prototype还是构造函数的属性。是不是乱了,反正我是傻了~~

  

三、prototype 和 __proto__ 区别:

  构造函数对应的是prototype,实例对象对应的是_proto_,两者都是相同的,都指向构造函数的原型。 

  例子:

function Demo(){
            this.name = "demo";
        }

        const demo = new Demo();

        console.dir(Demo.prototype);
        console.dir(demo.__proto__);
        console.log(Demo.prototype == demo.__proto__);

  

 四、相关的方法

  1.判断实例的构造函数:Object instanceof Function    和    Function.prototype.isPrototypeOf(Object)

  例如:

        function Demo(){
            this.name = "demo";
        }

        const demo = new Demo();

        console.log(demo instanceof Demo);
        console.log(Demo.prototype.isPrototypeOf(demo));

  

 2.检测属性来着与实例还是原型:hasOwnProperty()

例如:

function Demo(){
            this.name = "demo";
        }
        Demo.prototype.age = 11;

        const demo = new Demo();
        console.dir(demo.name+'.....'+demo.hasOwnProperty('name'));     //demo.....true
        console.dir(demo.age+'.....'+demo.hasOwnProperty('age'));       //11.....false

五、易混的概念

难点:

(1)函数即对象

在JS里,函数就是Function函数的实例对象,函数即是对象。

function Fun(){
            console.log('fun');
        }
        const fun1 = new Fun();         //对象由函数创建
        console.log(Fun.constructor);      //Function   结论:Fun 的构造函数是 Function
        console.log(Function.constructor);       //Function       结论:Function 的构造函数还是是 Function
        console.log(Object.constructor);        //Function       结论:Object 的构造函数还是是 Function
        //结论:对象由函数创建,函数都是Function函数的实例对象,也就是函数即对象

(2)constructor 的理解

 一个拿来保存自己构造函数引用的属性。由于同一个构造函数生成的实例的constructor 值的一样,为了节省内存空间,constructor被当成共享属性,存放在prototype(下文会介绍到)中。

(3)prototype 的理解

目的:为了内存着想,专门存放共享属性和方法的地方。 在自身存放在这些实例的构造函数上。又称为原型对象。

function Foo(){
            console.log('Foo');
        }

        const foo1 = new Foo();            //Foo
        const foo2 = new Foo();            //Foo
        //两个实例添加相同作用的方法
        foo1.say = function(){
            console.log('hello!!!');
        }
        foo2.say = function(){
            console.log('hello!!!');
        }
        console.log(foo1.say === foo2.say);        //false     //尽管二者的代码相同,但在我们的内存里,却存放了两份一模一样的东西,造成内存的浪费

        //prototype的好处:
        Foo.prototype.show = function(){
            console.log("This is a show function");
        }
        foo1.show();        // This is a show function
        foo2.show();        // This is a show function
        console.log(foo1.show === foo2.show);            //true         //这时,内存的存储空间也是相同的,没有造成浪费

(4)__proto__属性

目的:让实例能找到自己的原型对象

特点:只要是对象就会有__proto__属性

(5)原型链

 __proto__ 把原型对象和实例串起来的的形式,就是原型链

六、查阅的资料

  1. 阮一峰的网络日志
  2. 神秘者007-简书
  3. 用自己的方式(图)理解constructor、prototype、__proto__和原型链

原文地址:https://www.cnblogs.com/zxn-114477/p/14211035.html