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,如图:
所以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