关于JS原型以及原型链、instanceof的一些理解

一、JS原型

首先要区分两个概念

1、构造函数

2、实例:由构造函数通过new方式创建出来的就是实例

    <script>
        function Foo() {

        }

        var f = new Foo();
        console.log(f instanceof Foo);
    </script>

比如上面这段代码,f是由new Foo()出来的,那么f称为Foo的实例,Foo也称为f实例的构造函数

1、每一个函数都有一个属性 prototype,这个属性也称该函数的显示原型,prototype是一个空的object对象

2、每一个实例都有一个属性 __proto__,这个属性也称这个实例的原型对象,也称隐式原型

3、实例的原型对象(隐式原型)等于该实例构造函数的显示原型

4、所有通过new Foo()创建出来的实例的__proto__都指向Foo.prototype,所以这些实例的__proto__都是同一个原型对象

这个用上面的代码来说明的话,那就是

    <script>
        function Foo() {

        }

        var f = new Foo();
        var k = new Foo();

        //f是Foo的实例
        console.log(f instanceof Foo); //true

        //3、实例的原型对象(隐式原型)等于该实例构造函数的显示原型
        console.log(f.__proto__ === Foo.prototype);//true

        //4、所有通过new Foo()创建出来的实例的__proto__都指向Foo.prototype,所以这些实例的__proto__都是同一个对象
        console.log(k.__proto__ === f.__proto__);//true
    </script>

  

二、原型链

当试图得到一个实例的某个属性时,如果这个实例本身没有这个属性,那么会去它的_proto_里去找。

如果它的_proto_里没有这个属性,则去它_proto__proto_中去找,这样一直往上找,就形成了一个原型链。

    <script>
        function Foo() {
            this.age = 12;
        }
        Foo.prototype.name = "werben";

        var f = new Foo();
        
        //f这个实例本身有age属性,直接读取
        console.log(f.age); //output: 12
        
        //f这个实例本身没有name属性,那么会去它的_proto_里去找, 也就是Foo.prototype中去找name
        console.log(f.name); //output: werben
    </script>

  

 函数本身也是一个实例,是Function这个构造函数的实例,所以函数除了拥有prototype属性之外,它本身也拥有作为实例拥有的__proto__属性。

比如下面的代码,三种定义Foo函数的方式都是等价的。其中一种方式表明Foo也是Function的一个实例

    <script>
        
        function Foo() {
            console.log('hello world');
        }

        var Foo = function() {
            console.log('hello world');
        }

        var Foo = new Function(
            "console.log('hello world');"
        );

    </script>

  

原文地址:https://www.cnblogs.com/werben/p/11558697.html