js对象
bind/apply/call
总结一句话就是,这三个函数都是用于重新定义this 的
1 |
|
这个this 是获取的{}
这个对象里的
1 |
|
按道理来说这个this 会访问到外部的windows 从而获取name 但是为什么这个地方是undefine 呢?
引入一下几个问题
this是什么?
this 取决于函数的调用者,在ojb 方式中,调用者是obj ,所以this 也是obj。
为什么不会穿透到外部windows的原型?
这涉及到两个问题,**this
的动态绑定** 和 原型链的属性查找。this
的设计目标是决定“谁是这次调用的主角(上下文)”;而原型链的设计目标是解决“如果主角身上没有某个技能/属性,去哪里找”。this
的确定是“一锤子买卖”,在函数被调用的那一刻就定死了,它不会、也不需要通过原型链去“寻找”一个this
。
this
的世界:确定“执行上下文”
想象一下,this
就是一个舞台上的“主角”。一个函数(剧本)可以被不同的主角来表演。
this
的使命:在函数(剧本)执行的瞬间,指明当前是哪个对象(主角)在调用这个函数。它的核心是执行上下文(Execution Context)。确定时机
:
只在函数被调用的那一刻决定
。JS 引擎会看函数是怎么被叫来演出的。
student.sayHello()
:哦,是student
叫sayHello
来演出的,那这次演出的主角this
就是student
。sayHello()
:哦,没有主语,是直接在全局环境下叫的,那这次的主角this
就是window
(非严格模式)。sayHello.call(teacher)
:哦,导演用.call
强制指定了,那这次的主角this
就是teacher
。
this
的绑定过程非常霸道和直接,它只看“调用时”的场景,一旦确定,在本次函数执行期间就不可更改。它是一个动态绑定的机制,不是一个“查找”机制。
原型链的世界:进行“属性查找”
现在,主角 (this
) 已经确定了。主角要开始表演了,比如要念一句台词 this.name
或者施放一个技能 this.sayHello()
。
原型链的使命:如果发现主角(
this
对象)自己身上没有这个属性或方法(比如name
或sayHello
),那该去哪里找?原型链就是这个“寻找技能书/道具的路径”。查找过程
:
- 先看
this
对象本身有没有这个属性。 - 如果没有,就通过
this
对象的内部链接[[Prototype]]
(即__proto__
)找到它的原型对象。 - 在原型对象上查找该属性。
- 如果还没找到,就继续沿着原型对象的原型对象向上查找,直到链的尽头
Object.prototype
。 - 如果最终还是没找到,就返回
undefined
。
- 先看
这是一个纯粹的属性查找机制。
总结
this
的确定 和 原型链 是两码事。this
在调用时就定了,它不会通过原型链去“找”一个新的this
。window
不是所有对象的原型。window
是全局执行上下文的宿主对象。绝大多数普通对象的原型链最终指向的是Object.prototype
,而不是window
。window
本身也是一个对象,它的原型链也指向Object.prototype
。
- 函数调用发生时
this
绑定系统(看调用方式) -> 瞬间确定**主角this
**。- 执行函数代码
- 当代码中遇到
this.xxx
时… - 原型链系统(看
[[Prototype]]
链) -> 以已经确定的this
为起点,开始查找xxx
属性/方法。
- 当代码中遇到
var/let/const区别是什么?
var 会造成全局对象污染,所以在下面代码中能获取到name
Window 也是一个对象
在全局作用域中,
var
声明的变量会成为全局对象 (window
) 的属性。我们称这个行为是 “污染全局对象” 或 “污染全局命名空间”。
1 |
|
因此来分析下面这段代码
1 |
|
第一个shows 输出undefine
第一个show 输出august
- shows 和show 都的this 都是window 对象
- var 会污染window 对象,会挂载到window上,但是let 和 const 不会
因此可以得出结论
show 能输出,shows 不能
函数和原型对象的关系是什么?
函数是 实例
的工厂,原型对象是 实例
的模板。
揭秘call/apply/bind
1 |
|
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 **obj.myFun.call(db,’成都’, … ,’string’ )**。
apply 的所有参数都必须放在一个数组里面传进去 **obj.myFun.apply(db,[‘成都’, …, ‘string’ ])**。
bind 除了返回是函数以外,它 的参数和 call 一样。
箭头函数
1 |
|
定时器
1 |
|
setTimeout
:在指定延迟后执行一次任务,然后就停了。像一个“定时闹钟”。setInterval
:在指定延迟后开始执行任务,并每隔一个周期重复执行该任务。像一个“节拍器”。
Document 获取dom 的几个方式
方法 | 返回值 | 集合类型 | 性能 | 核心优势与建议 |
---|---|---|---|---|
getElementById() | 单个元素 | N/A | 最高 | 首选:当你知道 id 时,用它就对了。 |
getElementsByTagName() | HTMLCollection | 动态 | 很高 | 适用于获取特定标签类型的元素,但要注意动态集合的特性。 |
getElementsByClassName() | HTMLCollection | 动态 | 较高 | 适用于获取特定类的元素,同样要注意动态集合。 |
querySelector() | 单个元素 | N/A | 较好 | 主力:非常灵活,使用 CSS 选择器定位单个元素的首选。 |
querySelectorAll() | NodeList | 静态 | 较好 | 主力:批量获取元素的现代标准,返回静态集合更安全、可预测。 |