准备
// 准备函数 fun 传入两个参数
function fun(param1, param2){
// 输出 this,param1,param2
console.log(this, param1, param2)
// 返回 this 字符串
return this + ''
}
call
描述
- call 用一个指定的对象来调用函数,以指定的对象作为函数的 this 指向,然后传入一个或多个函数的参数
- 可以用它来实现继承操作
语法
function.call(thisArg, arg1, arg2, ...)
返回值
函数基于新传入的 this,执行后的返回值使用
```javascript fun.call(undefined, 1, 2) // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.call(null, 1, 2) // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.call(123, 1, 2) // 打印 Number {123} 1 2 // 返回 “123”
fun.call(false, 1, 2) // 打印 Boolean {false} 1 2 // 返回 “false”
fun.call(“你好”, 1, 2) // 打印 String {“你好”} 1 2 // 返回 “你好”
fun.call({a: “你好”}, 1, 2) // {a: “你好”} 1 2 // “[object Object]”
<a name="hPsrj"></a>
#### 模拟
```javascript
// 全局 this 考虑非浏览器环境,可能不为 window
const _this = this
Function.prototype.MyCall = function(...params) {
// 初始化 this 指向的对象
let objParam = params.shift(0)
// 如果是 undefined 或 null 使用全局 this
if(objParam === undefined || objParam === null){
objParam = _this
}
// 如果是基本类型,转化为对应的基本引用类型
else if(typeof objParam !== 'object'){
objParam = Object(objParam)
}
// 使用 symbol 防止对原对象中的方法覆盖
const keySymbol = Symbol('key')
objParam[keySymbol] = this
const result = objParam[keySymbol](...params)
// 删除
delete objParam[keySymbol]
return result
}
apply
描述
- apply() 方法,执行
- 可以用它来实现继承操作
语法
func.apply(thisArg, [argsArray])
返回值
函数基于新传入的 this,执行后的返回值使用
```javascript fun.apply(undefined, [1, 2]) // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.apply(null, [1, 2]) // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.apply(123, [1, 2]) // 打印 Number {123} 1 2 // 返回 “123”
fun.apply(false, [1, 2]) // 打印 Boolean {false} 1 2 // 返回 “false”
fun.apply(“你好”, [1, 2]) // 打印 String {“你好”} 1 2 // 返回 “你好”
fun.apply({a: “你好”}, [1, 2]) // {a: “你好”} 1 2 // “[object Object]”
<a name="1sjKo"></a>
#### 模拟
```javascript
// 全局 this 考虑非浏览器环境,可能不为 window
const _this = this
Function.prototype.MyApply = function(objParam, params) {
// 如果是 undefined 或 null 使用全局 this
if(objParam === undefined || objParam === null){
objParam = _this
}
// 如果是基本类型,转化为对应的基本引用类型
else if(typeof objParam !== 'object'){
objParam = Object(objParam)
}
// 使用 symbol 防止对原对象中的方法覆盖
const keySymbol = Symbol('key')
objParam[keySymbol] = this
const result = objParam[keySymbol](...params)
// 删除
delete objParam[keySymbol]
return result
}
bind
描述
- bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
- 绑定函数也可以使用 new 运算符构造,它会表现为目标函数已经被构建完毕了似的。提供的 this 值会被忽略,但前置参数仍会提供给模拟函数。
语法
function.bind(thisArg[, arg1[, arg2[, ...]]])
返回值
返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。使用
```javascript fun.bind(undefined, [1, 2])() // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.bind(null, [1, 2])() // 打印 Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …} 1 2 // 返回 “[object Window]”
fun.bind(123, [1, 2])() // 打印 Number {123} 1 2 // 返回 “123”
fun.bind(false, [1, 2])() // 打印 Boolean {false} 1 2 // 返回 “false”
fun.bind(“你好”, [1, 2])() // 打印 String {“你好”} 1 2 // 返回 “你好”
fun.bind({a: “你好”}, [1, 2])() // {a: “你好”} 1 2 // “[object Object]”
<a name="HQ4H7"></a>
#### 模拟
```javascript
// 全局 this 考虑非浏览器环境,可能不为 window
Function.prototype.MyBind = function(...params){
// 获取当前 this
const currentThis = this
// 获取对象
let objParam = params.shift()
// 创建新函数,为了处理 bind 中 new 的情况,单独使用变量存储新函数
return function() {
console.dir(this)
// 如果是 null 或者 undefined 指向全局
if(objParam === undefined || objParam === null){
objParam = _this
}
// 如果不是对象,转化为对应的对象
else if(typeof objParam !== 'object'){
objParam = Object(objParam)
}
// 如果是 new 操作,别修改 this
if(this instanceof arguments.callee){
objParam = this
}
// 使用 symbol 防止覆盖原来的方法
const keySymbol = Symbol('key')
objParam[keySymbol] = currentThis
const result = objParam[keySymbol](...params)
delete objParam[keySymbol]
return result
}
}