对原型 原型链 作用域链 和闭包的理解?

本文详细介绍了JavaScript中的原型链机制,解释了如何通过__proto__属性查找对象的属性,以及原型链的搜索过程。同时,也阐述了闭包的概念,它是函数作用域的副产品,允许内部函数访问外部变量。通过示例展示了闭包如何实现对变量的间接访问,强调了其在JavaScript编程中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原型
  • 每个对象都有__proto__属性,并且指向它们的原型对象。
  • 每个构造函数都有它的prototype原型对象。
  • prototype原型对象里面的constructor指向它的构造函数。
  • new一个构造函数会形成它的实例对象。

原型链
  • 当我们查找特定属性的时候,我们先去这个对象里面找,如果没有的话就去它的原型对象里面找,如果还没有的话就去原型对象原型对象找,这个操作就是被委托在整个原型链上。
    举个例子
  • 为什么有 valueOf / toString 属性呢?
var obj = { name:"obj"}
console.dir(obj)

原型对象
我们发现 console.dir(obj) 打出来的结果是:

  1. obj 本身有一个属性 name(这是我们给它加的)

  2. obj 还有一个属性叫做 __proto__(它是一个对象)

  3. obj.__proto__有很多属性,包括 valueOf、toString、constructor 等

  4. obj.__proto__其实也有一个叫做 __proto__的属性(console.log 没有显示),值为 null

现在回到我们的问题:obj 为什么会拥有 valueOf / toString / constructor 这几个属性?

答案:

这跟 __proto__ 有关。

当我们「读取」 obj.toString 时,JS 引擎会做下面的事情:

  1. 看看 obj 对象本身有没有 toString 属性。没有就走到下一步。

  2. 看看 obj.__proto__对象有没有 toString 属性,发现 obj.__proto__ 有 toString 属性,于是找到了

所以 obj.toString 实际上就是第 2 步中找到的obj.__proto__.toString

可以想象,

  1. 如果 obj.__proto__没有,那么浏览器会继续查看 obj.__proto__.__proto__

  2. 如果 obj.__proto__.__proto__也没有,那么浏览器会继续查看 obj.__proto__.__proto__.proto__

  3. 直到找到 toString 或者__proto__为 null。

上面的过程,就是「读」属性的「搜索过程」。

而这个「搜索过程」,是连着由 __proto__组成的链子一直走的。

这个链子,就叫做「原型链」。


闭包
  • 闭包就是能够读取其他函数内部变量的函数。
  • 闭包是 JS 函数作用域的副产品。
  • 换句话说,正是由于 JS 的函数内部可以使用函数外部的变量,所以这段代码正好符合了闭包的定义。而不是 JS 故意要使用闭包。
  • 暴露一个访问器(函数),让别人可以「间接访问」。而不是直接暴露在全局上。
var local = '变量';
function foo(){
	console.log(local)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码の搬运工

记录学习,记录认知,记录。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值