每日吃透一个面试题(1)-- 原型链

164 阅读2分钟

请讲一下你对原型链的理解?

原型链

1. 实例和构造函数的关系

  1. 每个函数都有一个prototype属性,该属性指向由该函数创建的实例对象的原型
  2. 每个对象都有一个__proto__属性,该属性指向该对象的原型
  3. 因此,构造函数与由它创建的实例对象的关系为:

	function Person() {}
	const person = new Person()
	console.log(Person.prototype === person.__proto__) // true

  1. 由此,构造函数和对象都可访问实例对象原型,原型是否可以访问构造函数和实例对象呢?
  2. 原型无法访问实例对象(毕竟一个构造函数可以生成多个实例对象,1对多情况下无法知道是哪个实例对象)
  3. 原型可以访问构造函数 ---- 通过constructor属性

	console.log(Person.prototype.constructor === Person) // true
	console.log(person.__proto__.constructor === Person) // true

2. 实例与原型的应用

  1. 读取一个对象的属性会沿着原型链查找,直到找到返回。

function Person() {}

Person.prototype.name = '小米'

var person = new Person()

person.name = '华为'
console.log(person.name) // 华为

delete person.name;
console.log(person.name) // 小米

// 先找 person.name 无再找person.__proto__.name 无再找 person.__proto__.__proto__.name...

3. 原型的原型

  1. 普通对象的原型的原型是null

	const obj = new Object()
	console.log(Object.prototype, Object.prototype.__proto__) // null
	console.log(obj.__proto__.__proto__) // null

4. 面试题解答

请讲一下你对原型链的理解?

答: 由于对象与对象之间是存在联系的,而js就是通过原型链来建立这种联系。首先,对象可以通过构造函数来创建,构造函数有一个prototype属性,该属性指向的是便是原型,但它不是该构造函数本身的原型,而是该构造函数创建的实例对象的原型。而通过构造函数new出来的实例对象有一个__proto__属性,该属性便指向它的原型,也就是说构造函数的prototype是等于通过该构造函数创建的实例对象的__proto__。当一个对象访问一个属性时,他会先在该对象本身查找,若没有找到,则会沿着原型链查找,也就是说,会到原型上找,在找不到就去原型的原型上找,直到找到或找到最后一层,有则返回该属性的值,没有就返回undefined。此外原型是可以通过constructor属性来访问其构造函数的。

5. 面试题延伸

请问创建对象有哪几种方式?

既然原型链有继承或者说代理访问的特性,那如何知道一个属性属于它本身还是在它的原型上,能不能确定在哪个原型上?

js如何实现继承?