前端面试:原型和原型链

本文详细介绍了JavaScript中的原型和原型链概念,包括构造函数、实例对象的__proto__属性、prototype属性以及它们之间的关系。通过示例展示了如何通过原型添加共享属性和方法,以及原型链在对象属性查找过程中的作用。同时,探讨了原型链在解决继承问题上的应用,并列举了常见的原型和原型链面试题。
摘要由CSDN通过智能技术生成

JS万物皆为对象,一个对象一般包含属性(变量)和方法(函数),其实属性和方法也是对象;

概念:

构造函数:使用了new关键字创建对象的函数,并返回一个对象,它绑定的this指向新创建的对象,并默认返回this

注意:声明构造函数的时候,为了规范用大写字母开头,用来区分是普通函数还是构造函数

function Student(name) {
	this.name = name
	this.hello = function () {
		console.log('Hello, ' + this.name + '!')
	}
}

let xiaoming = new Student('小明') // new 生成实例对象
xiaoming.name
xiaoming.hello()

console.log(xiaoming)	

原型对象:声明了函数之后,浏览器会按照一定的规则创建一个对象,这个对象就是原型对象,而这个原型对象实际上储存在了内存当中,简称原型

// xiaoming的隐式原型指向Student的显式原型
xiaoming.__proto__ === Student.prototype // true

xiaoming.constructor === Student.prototype.constructor // true
Student.prototype.constructor === Student // true

声明了一个函数之后,构造函数会有一个属性prototype(可称为显式原型),这个属性指向的就是这个构造函数对应的原型对象;

实例化的对象具有属性__proto__(可称为隐式原型),该对象调用这个属性可以直接访问到构造函数的原型对象;

function Student () {        
}
// 可以使用Student.prototype 直接访问到原型对象
Student.prototype.name = "哈哈"
Student.prototype.age = 20

let xiaohong = new Student()
console.log(xiaohong.name) // 哈哈

let xiaogang = new Student()
console.log(xiaogang.name)  // 哈哈  从原型中找到的,所以一样。

// 由于不能修改原型中的值,这种方法直接在xiaohong中添加了一个新的属性name,所以在xiaohong中无法再访问到原型中的属性
xiaohong.name = "小红"
console.log(xiaohong.name) // 小红

// 由于xiaogang中没有name属性,则对xiaogang来说仍然是访问的原型中的属性。    
console.log(xiaogang.name)  // 哈哈 

说明:

  • 创建xiaoming对象虽然使用的是Student构造函数,但是对象创建出来之后,这个xiaoming对象其实已经与Student构造函数没有关系了,xiaoming对象的__proto__属性指向的是Student构造函数的原型对象
  • 如果使用new Student()创建多个对象xiaohong、xiaogang...,则多个对象都会同时指向Student构造函数的原型对象
  • 我们可以手动给这个原型对象添加属性和方法,那么xiaohong、xiaogang...,这些对象就会共享这些在原型中添加的属性和方法
  • 如果我们访问xiaoming中的一个属性name,如果在xiaoming对象中找到,则直接返回。如果xiaoming对象中没有找到,则直接去xiaoming对象的__proto__属性指向的原型对象中查找,如果查找到则返回。(如果原型中也没有找到,则继续向上找原型的原型—,就是原型链)
  • 如果通过xiaoming对象添加了一个属性name,则xiaoming对象来说就屏蔽了原型中的属性name。 换句话说:在xiaoming中就没有办法访问到原型的属性name了
  • 通过xiaoming对象只能读取原型中的属性name的值,而不能修改原型中的属性name的值。 xiaoming.name = ‘李明’; 并不是修改了原型中的值,而是在xiaoming对象中给添加了一个属性name

原型链:原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构

红色箭头就是原型链,可以认为xiaomingxiaohong这些对象“继承”自Student

原型与原型链的常见面试题:

1、谈谈你对原型的理解

在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象,使用原型对象的好处是所有对象实例共享它所包含的属性和方法

2、什么是原型链?原型链解决的是什么问题

1)原型链解决的主要是继承问题
2)每个对象拥有一个原型对象,通过 proto 指针指向其原型对象,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向 null(Object.proptotype.__proto__指向的是null)。这种关系被称为原型链(prototype chain),通过原型链一个对象可以拥有定义在其他对象中的属性和方法
3)构造函数 Parent、Parent.prototype 和 实例 p 的关系如下:(p.__proto__ === Parent.prototype)

3、prototype 和 proto 区别是什么

1)prototype是构造函数的属性
2)__proto__是每个实例都有的属性,可以访问 [[prototype]] 属性
3)实例的__proto__与其构造函数的prototype指向的是同一个对象

https://www.liaoxuefeng.com/wiki/1022910821149312/1023022043494624

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值