当对象与原型有相同的属性,调用时的上下文指向问题

在查阅对象自定义事件及其触发实现的过程中,发现了如下代码:

即:构造函数的原型可以是其他构造方法new出来的对象实例,虽然理解构造函数原型就是一个对象,但通常都是用对象直接量来指定,如:F.prototype ={},这种用法,引起了一些思考:如果原型对象和构造函数定义了完全相同的属性,那么原型方法调研时,作用域是原型对象还是新的对象?为此,做了一下验证:

function ancestor(){
            this.name ='default';
            this.age = 18;
        }
        ancestor.prototype = {
            printInfo:function(){
                console.log( this.name + "," + this.age );
            }
        };
        function parent( _name,_age ){
            this.name = _name;
            this.age = _age;
        }
        parent.prototype = new ancestor();
        
        var o1 = new parent('tester',20);
        var o2 = new parent();
        console.log( o1 );
        console.log( o2 );

打印结果如下:

可见,对象原型和对象自身,都保留了各自的'name'和'age'属性,继续调用对象o1,o2继承自原型的printInfo方法,代码如下:

        function ancestor(){
            this.name ='default';
            this.age = 18;
        }
        ancestor.prototype = {
            printInfo:function(){
                console.log( this.name + "," + this.age );
            }
        };
        function parent( _name,_age ){
            this.name = _name;
            this.age = _age;
        }
        parent.prototype = new ancestor();
        
        var o1 = new parent('tester',20);
        var o2 = new parent();
        console.log('o1-----:');
        console.log( o1 );
        console.log('o2-----:');
        console.log( o2 );
        o1.printInfo();
        o2.printInfo();

执行结果:

可见:o1,o2在调用继承自原型的方法时,如果自身有了对应的属性定义,则调研的就是对象自身属性,不会上溯至原型对象

如想切换作用域至原型对象,可以利用方法的call方式来实现:

o1.printInfo.call(Object.getPrototypeOf(o1));
o2.printInfo.call(Object.getPrototypeOf(o2));

结果:

 -------------------------补充---------------------------------------------------------------------------------------------------

上面的情况下,当对象没有定义与原型重合的属性时,调用原型方法,会是什么情况?代码如下:

    function ancestor(){
            this.name ='default';
            this.age = 18;
        }
        ancestor.prototype = {
            printInfo:function(){
                console.log( this.name + "," + this.age );
            }
        };
        function parent(){

        }
        parent.prototype = new ancestor();
        
        var o1 = new parent();
        o1.printInfo();

运行结果:

可见,此时最终函数执行的作用域是其原型对象,其实这就是“作用域链”的概念:当对象的方法用到某属性时,会按照对象→原型parent1→原型parent2的链式方式,不断向上追溯查找该属性,直至找到或者为undefined.

路漫漫其修远兮,吾将上下而求索。 May stars guide your way⭐⭐⭐
原文地址:https://www.cnblogs.com/surfer/p/9681514.html