准备
// 准备函数 fun 传入两个参数function fun(param1, param2){// 输出 this,param1,param2console.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 考虑非浏览器环境,可能不为 windowconst _this = thisFunction.prototype.MyCall = function(...params) {// 初始化 this 指向的对象let objParam = params.shift(0)// 如果是 undefined 或 null 使用全局 thisif(objParam === undefined || objParam === null){objParam = _this}// 如果是基本类型,转化为对应的基本引用类型else if(typeof objParam !== 'object'){objParam = Object(objParam)}// 使用 symbol 防止对原对象中的方法覆盖const keySymbol = Symbol('key')objParam[keySymbol] = thisconst 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 考虑非浏览器环境,可能不为 windowconst _this = thisFunction.prototype.MyApply = function(objParam, params) {// 如果是 undefined 或 null 使用全局 thisif(objParam === undefined || objParam === null){objParam = _this}// 如果是基本类型,转化为对应的基本引用类型else if(typeof objParam !== 'object'){objParam = Object(objParam)}// 使用 symbol 防止对原对象中的方法覆盖const keySymbol = Symbol('key')objParam[keySymbol] = thisconst 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 考虑非浏览器环境,可能不为 windowFunction.prototype.MyBind = function(...params){// 获取当前 thisconst 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 操作,别修改 thisif(this instanceof arguments.callee){objParam = this}// 使用 symbol 防止覆盖原来的方法const keySymbol = Symbol('key')objParam[keySymbol] = currentThisconst result = objParam[keySymbol](...params)delete objParam[keySymbol]return result}}
