关于原型、原型链我所知道的

简介: 关于原型、原型链我所知道的

image.png


持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

结论:prototype 指向函数的原型对象,__proto__ 是指针。原型链则是通过 __proto__ 指向其原型对象,串联起链表。主要解决对象的继承问题。


什么是原型 prototype


JS 中的函数也是对象。如何证明函数也是对象?函数作为表达式被创建,并且可以添加任意的属性。

function fn() {}
fn.sex = 'male'
console.log(fn.sex) // male 函数可以添加任意的属性
// 利用 Object.create 方法,这个方法只有对象才能使用
function fn() {}
const obj = Object.create(fn); 
// Object.create('') 则会报错,报错内容: Object prototype may only be an Object or null
console.log(Object.getPrototypeOf(obj) === fn); // true


在 JS 中,每当定义一个对象的时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个 prototype 属性,这个属性指向函数的原型对象

使用原型对象的好处是所有对象实例共享它所包含的属性和方法。在做构造函数的时候经常会用到这个特性。


什么是原型链?什么是__proto__


__proto__ 是指针。原型链则是通过__proto__ 串联起来的链表。主要解决对象的继承问题。

先来看一段代码:

function Parent (name) {
  this.name = name
}
Parent.prototype.showName = function() {
  console.log(this.name)
}
const p = new Parent('kane')
p.showName()
console.log(p.__proto__ === Parent.prototype) // true


构造函数 Parent、Parent.prototype 和 实例 p 之间的关系:


image.png


每个实例对象都拥有一个原型对象,通过 __proto__ 指向其原型对象,并从中继承方法和属性。

同时原型对象也可能拥有他的原型对象,这样一层一层,最终指向 null(Object.proptotype.__proto__ 指向的是 null)。这种关系被称为原型链 (prototype chain)。

通过原型链,一个对象可以拥有定义在其他对象中的(继承过来的)属性和方法。


prototype__proto__ 区别是什么?


prototype 是构造函数的属性。

__proto__ 是每个实例都有的属性,可以访问 [[prototype]]

实例的 __proto__ 与其构造函数的 prototype 指向的是同一个对象。

function Parent (name) {
  this.name = name
}
Parent.prototype.showName = function() {
  console.log(this.name)
}
const p = new Parent('kane')
p.showName()
console.log(p.__proto__)
console.log(Object.getPrototypeOf(p))
console.log(Parent.prototype);
console.log(p.__proto__ === Parent.prototype) // true
class Human {
  constructor(name) {
    this.name = name;
  }
  say() {
    console.log('hello');
  }
}
class Man extends Human {
  constructor(name) {
    super(name);
  }
  run() {
    console.log('running')
  }
}
const man = new Man('kane')
man.say()
man.run()
console.log(Object.getPrototypeOf(man) === Man.prototype) // true
console.log(Object.getPrototypeOf(man) === Human.prototype) // false

image.png


如何实现 instanceof


特点

  1. 可以准确的判断复杂数据类型,但是不能正确判断基本数据类型
  2. 在原型链上的结果未必准确
  3. 不能检测 null,undefined

通过原型链判断的,A instanceof B:

  1. 在 A 的原型链中层层查找,是否有原型等于 B.prototype
  2. 如果一直找到 A 的原型链的顶端 (null; 即 Object.prototype.__proto__), 仍然不等于 B.prototype,那么返回 false,否则返回 true。
// L instanceof R
function myInstanceOf(L, R) {// L 表示左表达式,R 表示右表达式
  let O = R.prototype;// 取 R 的显式原型
  L = L.__proto__;    // 取 L 的隐式原型 
  // L = Object.getPrototypeOf(L) // 获取对象的原型
  while (true) {
      if (L === null) // 已经找到顶层
          return false;
      if (O === L)   // 当 O 严格等于 L 时,返回 true
          return true;
      L = L.__proto__;  // 继续向上一层原型链查找
  }
}
let a = [1,2,3]
console.log(myInstanceOf(a, String)); // false


目录
相关文章
|
4月前
|
JavaScript 前端开发
原型,原型链
原型,原型链
|
9月前
|
前端开发
前端原型和原型链构造函数的使用
前端原型和原型链构造函数的使用
49 0
|
9月前
|
前端开发
前端原型和原型链构造函数的使用
前端原型和原型链构造函数的使用
57 0
|
6月前
|
JavaScript 前端开发
原型和原型链
原型和原型链
20 0
|
9月前
|
JavaScript 前端开发
JavaScript 中的原型、对象原型、原型继承和原型链
在 JavaScript 中,原型(prototype)是一个对象,它用于实现对象之间的继承和共享属性。JavaScript 是一种基于原型的编程语言,每个对象都有一个原型,而原型又可以拥有自己的原型,形成一个原型链。
|
9月前
|
前端开发
前端原型和原型链constructor
前端原型和原型链constructor
58 0
|
10月前
|
存储 JavaScript 前端开发
深入理解原型与原型链
当我们在 JavaScript 中创建一个对象时,它会自动继承一个称为“原型”的对象。如果该对象访问一个属性或方法,但在自己的属性列表中找不到,它会沿着原型链向上查找,直到找到该属性或方法为止。在本篇文章中,我们将深入探讨 JavaScript 中的原型与原型链。
|
设计模式 JavaScript Java
理解,原型/原型链/new
理解,原型/原型链/new
89 0
|
前端开发 JavaScript
原型、原型链和继承~我终于搞定了啊~~
不管是在学习JavaScript,还是面试找工作,逃不过去的就是原型、原型链和继承这几个重点和难点;对于这些内容的掌握还是很有必要的。
92 0
原型、原型链和继承~我终于搞定了啊~~