不同环境的全局对象:
Node.js:
- global === globalThis ✓
- 没有 window
浏览器:
- window === globalThis ✓
- 没有 global
Web Worker:
- self === globalThis ✓
- 没有 window 和 global
总结: globalThis 在所有环境中都指向该环境的全局对象
// 手写实现call-apply-bind函数
// 将 myCall 添加到 Function.prototype 上
Function.prototype.myCall = function (context, ...args) {
if (typeof this !== 'function') {
throw new Error('myCall must be called on a function')
}
// 如果 context 为 null 或 undefined,则指向全局对象
context = context || globalThis
// context = context || (typeof window !== 'undefined' ? window : global)
// 使用 Symbol 避免属性名冲突
const fn = Symbol('fn')
context[fn] = this
const result = context[fn](...args)
delete context[fn]
return result
}
// 将 myApply 添加到 Function.prototype 上
Function.prototype.myApply = function (context, args) {
if (typeof this !== 'function') {
throw new Error('myApply must be called on a function')
}
context = context || globalThis
const fn = Symbol('fn')
context[fn] = this
const result = context[fn](...args)
delete context[fn]
return result
}
// 将 myBind 添加到 Function.prototype 上
Function.prototype.myBind = function (context, ...args) {
if (typeof this !== 'function') {
throw new Error('myBind must be called on a function')
}
const self = this
return function (...innerArgs) {
return self.myApply(context, [...args, ...innerArgs])
// return self.myCall(context, ...args, ...innerArgs)
/**
* context = context || globalThis
* const fn = Symbol('fn')
* context[fn] = self
* const result = context[fn](...args, ...innerArgs)
* delete context[fn]
* return result
*/
}
}
// 使用myCall
function test(a, b) {
console.log(this.value, a, b)
}
const obj = { value: 1 }
test.myCall(obj, 2, 3)
test.myApply(obj, [2, 3])
const bound = test.myBind(obj)
bound(2, 3)