3、JS的原型、原型链、执行上下文、作用域、作用域链+闭包(见1)
1、原型
1.1、函数的prototype属性
每个函数都有一个prototype属性,默认指向一个object空对象(即原型对象)
原型对象中有一个属性constructor,指向函数对象
1.2、给原型对象添加属性(一般添加方法)
函数的所有实例对象自动用于原型中的属性(方法)
// 原型对象中有一个属性constructor, 它指向函数对象 console.log(Date.prototype.constructor===Date)//true console.log(fn.prototype.constructor===fn)//true
1.3 显示原型和隐式原型
每个函数function都有一个prototype,即显示原型(属性),定义函数时自动添加
每个实例对象都有一个__proto__,称为隐式原型,创建对象实例时自动添加
对象的隐式原型的值对应其构造函数的显示原型的值(保存的是同一个地址)
2、原型链+instanceof
2.1 访问一个对象的属性时,先在自身属性中查找,
如果没有,再沿着__proto__这条链向上查找,找到返回,没找到返回undefined
//所有的函数都是Function的实例(包含Function,是它自身的实例) console.log(Function.__proto__===Function.prototype) //Object的原型对象(Object.prototype)是原型链的尽头 console.log(Object.prototype.__proto__)
2.2设置原型属性值时,不会查找原型链,如果当前对象中没有此属性,就直接添加
2.3 instanceof是按照原型链来判断的, typeof是返回数据类型的字符串表达式
3、执行上下文
3.1代码分类
全局代码
局部(函数)代码
3.2全局执行上下文
在执行全局代码之前,将window确定为全局执行上下文
对全局数据进行预处理(var声明的全局变量,function声明的全局函数,this赋值window)
开始执行全局代码
3.3 函数执行上下文(只有在调用的时候才会产生)
调用函数之前,创建相应的函数执行上下文
对局部数据进行预处理(形参赋值实参; 实参列表arguments; function声明的函数; this赋值)
开始执行局部代码
3.4 函数执行上下文栈
后来的先执行
3.5 测试
/* 测试题1: 先预处理变量, 后预处理函数 先执行变量提升,在执行函数提升 */ function a() {} var a; console.log(typeof a)//function
/* 测试题2: 变量预处理, in操作符 */ if (!(b in window)) { var b = 1; } console.log(b)//undefined /* 测试题3: 预处理, 顺序执行 */ var c = 1 function c(c) { console.log(c) var c = 3 } c(2)//报错,而且函数c没有机会执行 //执行顺序相当为 // var c // function c(c) { // console.log(c) // var c = 3 // } //c = 1 // c(2)
4、作用域和作用域链
全局作用域、函数作用域,
在定义时就已经确定了,注意和上下文环境的区别,并且上下文环境是从属于所在的作用域的
作用域链:嵌套的作用域,多个上下级关系的作用域形成的链
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!