js对象

bind/apply/call

总结一句话就是,这三个函数都是用于重新定义this 的

1
2
3
4
5
6
7
8
9
10
const obj={
name:"august",
work: "developer",
do: function(){
console.log(this.name+" is doing..."+this.work)
}
}

obj.do()

image-20250607171352301

这个this 是获取的{} 这个对象里的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const obj={
do: function(){
console.log(this.name+" is doing..."+this.work)
}
}


const name="august"
const work="design"


// obj.do.bind(info)()


obj.do()

image-20250607171620030

按道理来说这个this 会访问到外部的windows 从而获取name 但是为什么这个地方是undefine 呢?

引入一下几个问题

this是什么?

this 取决于函数的调用者,在ojb 方式中,调用者是obj ,所以this 也是obj。

为什么不会穿透到外部windows的原型?

这涉及到两个问题,**this 的动态绑定** 和 原型链的属性查找
this 的设计目标是决定“谁是这次调用的主角(上下文)”;而原型链的设计目标是解决“如果主角身上没有某个技能/属性,去哪里找”。this 的确定是“一锤子买卖”,在函数被调用的那一刻就定死了,它不会、也不需要通过原型链去“寻找”一个this

this 的世界:确定“执行上下文”

想象一下,this 就是一个舞台上的“主角”。一个函数(剧本)可以被不同的主角来表演。

  • this 的使命:在函数(剧本)执行的瞬间,指明当前是哪个对象(主角)在调用这个函数。它的核心是执行上下文(Execution Context)

  • 确定时机

    只在函数被调用的那一刻决定

    。JS 引擎会看函数是怎么被叫来演出的。

    • student.sayHello():哦,是 studentsayHello 来演出的,那这次演出的主角 this 就是 student
    • sayHello():哦,没有主语,是直接在全局环境下叫的,那这次的主角 this 就是 window(非严格模式)。
    • sayHello.call(teacher):哦,导演用 .call 强制指定了,那这次的主角 this 就是 teacher

this 的绑定过程非常霸道和直接,它只看“调用时”的场景,一旦确定,在本次函数执行期间就不可更改。它是一个动态绑定的机制,不是一个“查找”机制。

原型链的世界:进行“属性查找”

现在,主角 (this) 已经确定了。主角要开始表演了,比如要念一句台词 this.name 或者施放一个技能 this.sayHello()

  • 原型链的使命:如果发现主角(this 对象)自己身上没有这个属性或方法(比如 namesayHello),那该去哪里找?原型链就是这个“寻找技能书/道具的路径”

  • 查找过程

    1. 先看 this 对象本身有没有这个属性。
    2. 如果没有,就通过 this 对象的内部链接 [[Prototype]](即 __proto__)找到它的原型对象。
    3. 在原型对象上查找该属性。
    4. 如果还没找到,就继续沿着原型对象的原型对象向上查找,直到链的尽头 Object.prototype
    5. 如果最终还是没找到,就返回 undefined

这是一个纯粹的属性查找机制。

总结

  1. this 的确定原型链 是两码事。this 在调用时就定了,它不会通过原型链去“找”一个新的this
  2. window 不是所有对象的原型window 是全局执行上下文的宿主对象。绝大多数普通对象的原型链最终指向的是 Object.prototype,而不是 windowwindow 本身也是一个对象,它的原型链也指向 Object.prototype
  • 函数调用发生时
    1. this 绑定系统(看调用方式) -> 瞬间确定**主角 this**。
    2. 执行函数代码
      • 当代码中遇到 this.xxx 时…
      • 原型链系统(看 [[Prototype]] 链) -> 以已经确定的 this 为起点,开始查找 xxx 属性/方法

var/let/const区别是什么?

var 会造成全局对象污染,所以在下面代码中能获取到name

Window 也是一个对象

在全局作用域中,var 声明的变量会成为全局对象 (window) 的属性。我们称这个行为是 “污染全局对象”“污染全局命名空间”

1
2
3
4
5
6
7
var name="august";

function show(){
console.log(this.name)
}

show()

因此来分析下面这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const fav='盲僧'; // or let fav='盲僧';
function shows(){
console.log(this.fav);
}

shows();

var name="august";

function show(){
console.log(this.name)
}

show()

第一个shows 输出undefine

第一个show 输出august

  1. shows 和show 都的this 都是window 对象
  2. var 会污染window 对象,会挂载到window上,但是let 和 const 不会

因此可以得出结论

show 能输出,shows 不能

函数和原型对象的关系是什么?

函数是 实例 的工厂,原型对象是 实例 的模板。

image-20250607184753902

image-20250607184746673

揭秘call/apply/bind

1
2
3
4
5
6
// 将p 和eat 绑定,现在函数的this指向p
eat.call(p,data)
eat.apply(p,data)
eat.bind(p,data)() //bind 返回一个函数需要二次调用


image-20250607185254694

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:

call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 **obj.myFun.call(db,’成都’, … ,’string’ )**。

apply 的所有参数都必须放在一个数组里面传进去 **obj.myFun.apply(db,[‘成都’, …, ‘string’ ])**。

bind 除了返回是函数以外,它 的参数和 call 一样。

箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
arr=[1,2,3,4,5]
ret=arr.map((item)=>{return item*item})
console.log(ret)

ret=arr.map(i => i*i)
console.log(ret)


ret=arr.map(function (item) {
return item*item
})
console.log(ret)


定时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// 1. 设置一个 interval 定时器
const intervalID = setInterval(function() {
console.log("来自 setInterval: hello yuan");
}, 1000);

console.log("setInterval 的 ID 是:", intervalID);

// 2. 设置一个 timeout 定时器
const timeoutID = setTimeout(function() {
// 这个回调函数永远不会执行
console.log("来自 setTimeout: hello yuan");
}, 3000);

console.log("setTimeout 的 ID 是:", timeoutID);

// 3. 立即清除 timeout 定时器
clearTimeout(timeoutID);
console.log(`ID 为 ${timeoutID} 的 setTimeout 已被清除。`);

// 4. 在需要的时候清除 interval 定时器(例如,5秒后)
setTimeout(function() {
clearInterval(intervalID); // 注意:清除 interval 用 clearInterval
console.log(`ID 为 ${intervalID} 的 setInterval 已在 5 秒后被清除。`);
}, 5000);
  • setTimeout:在指定延迟后执行一次任务,然后就停了。像一个“定时闹钟”。
  • setInterval:在指定延迟后开始执行任务,并每隔一个周期重复执行该任务。像一个“节拍器”。

Document 获取dom 的几个方式

方法 返回值 集合类型 性能 核心优势与建议
getElementById() 单个元素 N/A 最高 首选:当你知道 id 时,用它就对了。
getElementsByTagName() HTMLCollection 动态 很高 适用于获取特定标签类型的元素,但要注意动态集合的特性。
getElementsByClassName() HTMLCollection 动态 较高 适用于获取特定类的元素,同样要注意动态集合。
querySelector() 单个元素 N/A 较好 主力:非常灵活,使用 CSS 选择器定位单个元素的首选。
querySelectorAll() NodeList 静态 较好 主力:批量获取元素的现代标准,返回静态集合更安全、可预测。

js对象
https://tsy244.github.io/2025/06/07/js逆向/js对象/
Author
August Rosenberg
Posted on
June 7, 2025
Licensed under