美文网首页
js 中的原型和原型链

js 中的原型和原型链

作者: downhill6 | 来源:发表于2019-04-24 01:52 被阅读0次

什么是原型?

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个 prototype 属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向prototype 属性所在函数的指针。举例:

const Person = function(name) {
    this.name = name
}
console.log(Person.prototype.constructor === Person) // true

在上例中,Person.prototype.constructor 指向 Person。而通过这个构造函数,我们还可继续为原型对象添加其他属性和方法。

实例对象与构造函数的关系

const person1 = new Person('小明')
console.log(person1) // Person {name: "小明"}

上面的 person1 就是实例对象,Person 就被我们叫做 构造函数

构造函数的 prototype 属性与它创建的实例对象的[[prototype]]属性指向的是同一个对象,即 实例对象.__proto__ === 构造函数.prototype,所以:

console.log(person1.__proto__ === Person.prototype) // true

原型链

  • 每个对象都拥有一个隐藏的属性[[prototype]],指向它的原型对象,这个属性可以通过Object.getPrototypeOf(obj)obj.__proto__ 来访问。

  • 原型对象同样也有一个隐藏的属性[[prototype]],指向它的原型对象。

  • 通过__proto__ 属性将对象和原型连接起来,就组成了原型链。

原型链的作用

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
下面的示例来自MDN

// 让我们从一个自身拥有属性a和b的函数里创建一个对象o:
let f = function () {
   this.a = 1;
   this.b = 2;
}

let o = new f(); // o: {a: 1, b: 2}
// 在f函数的原型上定义属性
f.prototype.b = 3;
f.prototype.c = 4;

/* 
不要在f函数的原型上直接定义 f.prototype = {b:3,c:4};这样会直接打破原型链
o.[[Prototype]] 有属性 b 和 c   (其实就是o.__proto__或者o.constructor.prototype)
o.[[Prototype]].[[Prototype]] 是 Object.prototype.
最后o.[[Prototype]].[[Prototype]].[[Prototype]]是null
这就是原型链的末尾,即 null,
根据定义,null 没有[[Prototype]].
综上,整个原型链如下: 
{a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null
*/
console.log(o.a); // 1
//a是o的自身属性吗?是的,该属性的值为1

console.log(o.b); // 2
// b是o的自身属性吗?是的,该属性的值为2
// 原型上也有一个'b'属性,但是它不会被访问到.这种情况称为"属性遮蔽 (property shadowing)"

console.log(o.c); // 4
// c是o的自身属性吗?不是,那看看原型上有没有
// c是o.[[Prototype]]的属性吗?是的,该属性的值为4

console.log(o.d); // undefined
// d是o的自身属性吗?不是,那看看原型上有没有
// d是o.[[Prototype]]的属性吗?不是,那看看它的原型上有没有
// o.[[Prototype]].[[Prototype]] 为 null,停止搜索
// 没有d属性,返回undefined

总结

  • Object 是所有对象的爸爸,所有对象都可以通过 __proto__ 找到它
  • Function 是所有函数的爸爸,所有函数都可以通过 __proto__ 找到它
  • 函数的 prototype 是一个对象
  • 对象的 __proto__ 属性指向原型, __proto__ 将对象和原型连接起来组成了原型链
  • 对象里找不到的属性会到原型里去找

相关文章

  • 2022前端高频面试题

    JS相关 1.原型和原型链是什么 原型和原型链都是来源于对象而服务于对象的概念js中引用类型都是对象,对象就是属性...

  • JavaScript原型对象与原型链

    一、前言 原型和原型链是 JavaScript中不可避免需要碰到的知识点,在刚开始学习 JS 时,原型和原型链都是...

  • 深入javascript之原型和原型链

    原型和原型链是js中的难点也是重点,明白了原型和原型链会让我们在后面不管是学习还是工作都会更加高效,并且原型和原型...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • javascript中的原型链与继承

    javascript中的原型链与继承javascipt中的原型链和继承机制是这门语言所特有的,但js中的原型机制也...

  • 原型对象和原型链二者的关系

    开篇 之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)...

  • 一个例子让你彻底明白原型对象和原型链

    开篇 之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)...

  • 原型和原型链的简单理解

    原型 在JS中原型就是prototype对象,用来表示类型之间的关系。 原型链 JS中对象和对象之间是有联系的,通...

  • 原型与新版的类-class

    首先来理解原型原型 === 共用属性可以先看看方姐的几篇文章:什么是JS原型链JS 中 proto 和 proto...

网友评论

      本文标题:js 中的原型和原型链

      本文链接:https://www.haomeiwen.com/subject/kdgigqtx.html