js 原型题

一、prototype、 __proto__、 constructor 三者关系

过程1:只要创建一个函数Foo,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象

过程2:原型对象会默认去取得constructor属性,指向构造函数。

过程3:当调用构造函数创建一个新实例 foo后,该实例的内部将包含一个指针__proto__,指向构造函数的原型对象。

function Foo(){};
var foo = new Foo();

1)第一行代码定义了一个函数,此时就发生了过程1和过程2



所以 Foo.prototype.constructor === Foo的运行结果为true

2)再来看看第二行代码

第二行代码创建了一个实例,发生了过程3,如图:

image
所以foo.__proto__ === Foo.prototype运行结果为true
可以发现实例foo与构造函数之间是没有直接联系的,所有关系都是通过Foo的原型对象连接起来的。
实例对象foo与Foo之间没有直接联系,但foo继承了Foo的原型对象的constructor的属性,有了间接的联系。

二、与原型有关的面试题
与原型有关的面试题除了会问到这三者的关系外,还会改变原型链来进行考察,如下:

var fun = function(){}

fun.prototype = { 
name : 'peter', 
age : 25 
}

var a = new fun();
var b = new fun();
console.log(a.name, b.name);//peter peter
fun.prototype.name = 'jack';
console.log(a.name, b.name);//jack jack
//重写原型
fun.prototype = {};
fun.prototype.name = 'tom';
console.log(a.name, b.name);//jack jack
b.constructor.prototype.name = 'kitty';
console.log(a.name, b.name);//jack jack


若想要输出tom该怎么改,为什么不能输出kitty? 

(1)、fun.prototype ={}是重写原型,重写后跟重写前就已经实例化的对象没有关系的,所以Tom自然不生效。若要输出tom,添加以下代码

  a.__proto__.name=tom,无法通过fun来实现,因为原型链已断

(2)、 不能输出kitty是因为b.contructor!=fun,在刚开始的时候fun的原型就被重写了。可以改为

           fun.prototype={
                name:''peter'',

                constructor:fun,

                age:25

           }
参考文章:
https://blog.csdn.net/fengyinchao/article/details/52042438
https://www.cnblogs.com/youhong/p/6838611.html

 

posted on 2021-03-16 14:45  代码老丸子  阅读(166)  评论(0编辑  收藏  举报

导航