js原型链面试常见问题

本文详细介绍了JavaScript中的原型链概念,包括其在对象继承中的作用,如何通过原型链实现继承,以及原型链查找属性的规则。还讨论了原型污染的问题和__proto__与prototype的区别,强调了安全使用原型的重要性和编程实践。
摘要由CSDN通过智能技术生成

原型链是 JavaScript 中的一个重要概念,面试中经常会被问到。以下是一些常见的面试题:

  1. 解释什么是原型链? 这个问题是为了测试你是否理解原型链的基本概念。你可以解释原型链是 JavaScript 实现对象间继承的主要机制,每个对象都有一个指向其原型(即创建该对象的构造函数的 prototype 属性)的内部链接。

详解:原型链是 JavaScript 中实现对象间继承的主要机制。每个对象都有一个指向其原型(即创建该对象的构造函数的 prototype 属性)的内部链接,这个链接被称为 [[Prototype]]。原型对象也可能有自己的原型,形成了一个原型链。当试图访问一个对象的属性时,如果对象自身没有这个属性,那么 JavaScript 会沿着原型链去查找。如果沿着原型链都找不到这个属性,那么返回 undefined

function Person() {}

Person.prototype.sayHello = function() {

  return 'Hello, World!';

}

let person1 = new Person();

console.log(person1.sayHello());  // 输出 "Hello, World!"

在这个例子中,person1 对象没有 sayHello 方法,但是它的原型 Person.prototype 有这个方法,所以 person1.sayHello() 可以正确地执行。

   2.如何通过原型链实现继承? 这个问题是为了测试你是否知道如何使用原型链来实现继承。你可以解释使用构造函数和 prototype 属性来实现继承,或者使用 Object.create 方法。

在 JavaScript 中,我们可以通过原型链来实现继承。每个对象都有一个 [[Prototype]] 属性,这个属性链接到它的原型对象。当我们试图访问一个对象的属性时,如果对象自身没有这个属性,那么 JavaScript 会沿着原型链去查找。

为了通过原型链实现继承,我们可以将子类的原型设置为父类的实例。这样,子类的实例就可以访问父类原型上的属性和方法。同时,我们还需要在子类的构造函数中调用父类的构造函数,以继承父类的实例属性。 

function Parent() {

    this.name = 'parent';

}

Parent.prototype.sayName = function() {

    console.log(this.name);

}

function Child() {

    Parent.call(this);

}

Child.prototype = new Parent();

Child.prototype.constructor = Child;

let child = new Child();

child.sayName();  // 输出 "parent"

在这个例子中,Child 通过 Parent.call(this) 继承了 Parent 的实例属性,通过 Child.prototype = new Parent() 继承了 Parent 的原型方法。这就是如何通过原型链实现继承。

需要注意的是,这只是一种基本的实现方式,实际上还有很多其他的方式可以实现继承,例如使用 Object.create 方法等。

3.原型链查找属性或方法时,如果找不到会发生什么? 这个问题是为了测试你是否理解原型链的工作原理。你可以解释,当试图访问一个对象的属性或方法时,如果对象自身没有这个属性或方法,那么 JavaScript 会沿着原型链去查找。如果沿着原型链都找不到这个属性或方法,那么返回 undefined。

4.什么是原型污染? 这个问题是为了测试你是否理解原型链的一些潜在问题。你可以解释,原型污染是指通过修改原型添加或修改属性或方法,导致所有继承自该原型的对象都被改变。

原型污染,也被称为原型污染攻击或原型覆盖,是一种 JavaScript 的安全漏洞。它发生在当恶意代码通过修改原型添加或修改属性或方法,导致所有继承自该原型的对象都被改变。

Object.prototype.foo = "bar";

这段代码添加了一个新的属性 foo 到 Object.prototype。由于几乎所有的 JavaScript 对象都是从 Object.prototype 继承的,这意味着几乎所有的对象现在都有了这个新的 foo 属性。这就是原型污染。

原型污染可能会导致各种问题,包括数据泄露、应用崩溃或其他未预期的行为。因此,我们应该避免修改内置对象的原型,除非我们完全理解可能的后果。

5.解释 __proto__ 和 prototype 的区别? 这个问题是为了测试你是否理解这两个属性的区别。你可以解释,__proto__ 是每个实例对象(Object)都具有的属性,指向它的构造函数的原型对象(prototype)。prototype 是构造函数的属性,指向实例对象的原型对象。

__proto__ 和 prototype 是 JavaScript 中的两个属性,它们都与原型链和继承有关,但是它们的用途和含义是不同的。

  1. __proto__:这是每个对象都有的一个属性,它指向了创建该对象的构造函数的原型。也就是说,obj.__proto__ 就是创建 obj 对象的构造函数的 prototype。这个属性是 JavaScript 的内部机制,虽然在很多浏览器中可以直接访问,但在 ES6 之前并不是标准的一部分。在 ES6 中,__proto__ 被包含在了语言规范中,主要是为了保持向后兼容。

  2. prototype:这是函数才有的一个属性。当一个函数被用作构造函数来创建实例时,这个函数的 prototype 就会成为实例对象的原型。也就是说,如果我们有 let obj = new SomeConstructor(),那么 SomeConstructor.prototype 就是 obj 的原型。

总的来说,__proto__ 是对象的属性,指向了对象的原型,而 prototype 是函数的属性,当函数被用作构造函数创建实例时,函数的 prototype 就会成为实例的原型。

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值