什么是原型链和作用域链?

简介: 什么是原型链和作用域链?

1.作用域链


JavaScript 在执⾏过程中会创建一个个的可执⾏上下⽂。 (每个函数执行都会创建这么一个可执行上下文)

每个可执⾏上下⽂的词法环境中包含了对外部词法环境的引⽤,可通过该引⽤来获取外部词法环境中的变量和声明等。


这些引⽤串联起来,⼀直指向全局的词法环境,形成一个链式结构,被称为作⽤域链。


简而言之: 函数内部 可以访问到 函数外部作用域的变量, 而外部函数还可以访问到全局作用域的变量,


这样的变量作用域访问的链式结构, 被称之为作用域链

let num = 1
function fn () {
  let a = 100
  function inner () {
    console.log(a)
    console.log(num)
  }
  inner()
}
fn()

下图为由多个可执行上下文组成的调用栈:

  • 栈最底部为全局可执行上下文
  • 全局可执行上下文 之上有多个 函数可执行上下文
  • 每个可执行上下文中包含了指向外部其他可执行上下文的引用,直到 全局可执行上下文 时它指向 null

image.png

image.png

js全局有全局可执行上下文, 每个函数调用时, 有着函数的可执行上下文, 会入js调用栈

每个可执行上下文, 都有者对于外部上下文词法作用域的引用, 外部上下文也有着对于再外部的上下文词法作用域的引用

=> 就形成了作用域链

2.原型链


要讲清楚这个问题,主要着重这几个方面:

  • 什么是原型对象
  • 构造函数, 原型对象, 实例的三角关系图
  • 原型链如何形成

image.png

原型对象

在 JavaScript 中,除去一部分内建函数,绝大多数的函数都会包含有一个叫做 prototype 的属性,指向原型对象,

基于构造函数创建出来的实例, 都可以共享访问原型对象的属性。

例如我们的 hasOwnProperty, toString ⽅法等其实是 Obejct 原型对象的方法,它可以被任何对象当做⾃⼰的⽅法来使⽤。

hasOwnProperty 用于判断, 某个属性, 是不是自己的 (还是原型链上的)

来看一段代码:

let person = { 
  name: "Tom", 
  age: 18, 
  job: "student"
}
console.log(person.hasOwnProperty("name")) // true 
console.log(person.hasOwnProperty("hasOwnProperty")) // false 
console.log(Object.prototype.hasOwnProperty("hasOwnProperty")) // true

可以看到,hasOwnProperty 并不是 person 对象的属性,但是 person 却能调用它。

那么 person 对象是如何找到 Object 原型中的 hasOwnProperty 的呢?这就要靠原型链的能力了。

原型链

在 JavaScript 中,每个对象中都有一个 __proto__ 属性,这个属性指向了当前对象的构造函数的原型。

对象可以通过自身的 __proto__属性与它的构造函数的原型对象连接起来,

而因为它的原型对象也有 __proto__,因此这样就串联形成一个链式结构,也就是我们称为的原型链。

image.png


相关文章
|
7月前
|
JavaScript 前端开发
作用域链的理解
作用域链的理解
64 0
|
2月前
|
设计模式 JavaScript 前端开发
原型链
【10月更文挑战第9天】
|
2月前
|
设计模式 JavaScript 前端开发
原型链在哪些场景下比较适用
【10月更文挑战第13天】原型链在哪些场景下比较适用
44 0
|
JavaScript 前端开发
什么是原型链
什么是原型链
|
7月前
|
自然语言处理 JavaScript 前端开发
深入理解作用域、作用域链和闭包
在 JavaScript 中,作用域是指变量在代码中可访问的范围。理解 JavaScript 的作用域和作用域链对于编写高质量的代码至关重要。本文将详细介绍 JavaScript 中的词法作用域、作用域链和闭包的概念,并探讨它们在实际开发中的应用场景。
|
7月前
|
自然语言处理 JavaScript 前端开发
对作用域链的理解
对作用域链的理解
61 0
38 # 简单描述原型链
38 # 简单描述原型链
35 0
|
JavaScript 前端开发
什么是原型链?
什么是原型链?
183 0
|
存储 JavaScript 前端开发
从执行上下文和作用域链理解闭包
从执行上下文和作用域链理解闭包
110 0
从执行上下文和作用域链理解闭包
掌握原型链,再炒冷饭系列
我们知道每一个函数都有一个自身的prototype,每一个对象都有__proto__对象,而这个__proto__我们常称之为隐式原型,正因为它连接起了对象与构造函数的关系。 当我们访问一个对象时,首先会在自身属性上找,当自身属性找不到时,会到对象的隐式链上去找,如果隐式链上还没有,那么会到构造函数的原型上找,当原型上没有时,会到原型的隐式__proto__上去找,当这个属性还找不到时,就直接返回undefined了,因此才形成了一条原型链。
103 0
掌握原型链,再炒冷饭系列