VUE框架prototype原型对象添加属性和方法原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app"></div>
    <script>
        const users = Vue.extend({
            template : `
            <div>
                <h1>哈哈哈</h1>    
            </div>
            `,
            mounted()
            {
                // 这里的this是VueComponent实例对象
                // users是什么呢?是一个全新的构造函数VC构造函数
                console.log(this === users);
            }
        });
        const vm = new Vue({
            el : "#app",
            template : `<users></users>`,
            components : {users},
            mounted(){
                // 这个this是VUE实例对象
                console.log(this);
            }
        });
        function test()
        {
            var Sub = function User(){
                this.name = 'admin';
            }
            return Sub;
        }
        let a = test();
        console.log(a);
        let b = test();
        console.log(b);
        console.log(a === b);
        // 构造函数
        function Vip(){
 
        }
        function User(){
 
        }
        // 函数本身又是一种类型,代表VIP类型
        // VIP类型/VIP构造函数有一个prototype属性
        // 这个prototype属性可以称为显式的原型属性
        // 这里就获取了这个VIP的原型对象
        // 一般使用这个类型.prototype即可
        // 这两个方法和JAVA的反射机制类似
        let x = Vip.prototype;
        let a1 = new Vip();
        // let a2 = new Vip();
        // let a3 = new Vip();
        // 对于实例来说都有一个隐式的原型属性__proto__
        // 不建议程序员使用
        // 这种方式也可以获取VIP的原型对象
        let y = a1.__proto__;
        // 获取的原型对象是一致的
        // 因为原型对象只有一个,其实只要是同一个类,原型对象就是共享的
        console.log(x === y);
        // a2.__proto__;
        // a3.__proto__;
        // User.prototype
        Vip.prototype.counter = 1000;
        // 这个不是给VIP拓展属性
        // 这是给VIP的原型对象拓展属性
        // 我们在学习JS的时候,就是用这个方式拓展属性和方法的
        console.log(a1.counter);
        // 其实对于对象来说,从始至终,他身上都没有那个属性
        // 这个的实现原理是,其实从始至终,我们都没有操作到a1对象
        // 但是,当我们访问a1对象总没有的属性或者方法的时候
        // 它会自动向上寻,在原型对象总寻找,找到了就可以获取
        // 因此在底层执行的是
        console.log(a1.__proto__.counter);
    </script>
</body>
</html>