apply()
方法接收一个指定的this
值和一个包含多个参数的数组来调用一个函数。javascript
call()
方法接收一个指定的 this
值和一个参数列表来调用一个函数。前端
bind()
方法建立一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其他参数将做为新函数的参数,供调用时使用java
使用 call
和 apply
函数的时候要注意,若是传递给 this
的值不是一个对象,JavaScript 会尝试使用内部 ToObject
操做将其转换为对象。所以,若是传递的值是一个原始值好比 7
或 'foo'
,那么就会使用相关构造函数将它转换为对象,因此原始值 7
会被转换为对象,像 new Number(7)
这样,而字符串 'foo'
转化成 new String('foo')
这样,例如:数组
function bar() {
console.log(Object.prototype.toString.call(this));
}
//原始值 7 被隐式转换为对象
bar.call(7); // [object Number]
bar.call('foo'); // [object String]
复制代码
func.apply(thisArg, [argsArray])
闭包
thisArg
必选的。在 func
函数运行时使用的 this
值。若是这个函数处于非严格模式下,则指定为 null
或 undefined
时会自动替换为指向全局对象,原始值会被包装。func
函数。Function.prototype.Apply = function (thisArg, args = Symbol.for('args')) {
//Apply 函数老是被咱们想改变this的函数调用,所以本函数内this老是指代调用函数
//生成一个Symbol类型的惟一符号,用于将调用apply的函数挂载到指定对象上
const fn = Symbol('fn')
thisArg[fn] = this
//经过对象调用函数,并传参
args === Symbol.for('args') ? thisArg[fn]() : thisArg[fn](...args)
//删除挂载到指定对象上的方法
delete thisArg[fn]
}
// 声明全局变量
var position = 'global'
var name = 'window'
function func(name) {
console.log(this.position)
console.log(name)
}
const obj = {
name: 'object',
position: 'obj',
}
func.Apply(obj,[obj.name,null]) // obj object
// 其中,Apply内this指向func
func.Apply(obj,[name,null]) // obj window
// func中 name 只受传参影响
复制代码
Symbol.for(key)
会根据给定的键key
,来从运行时的 symbol 注册表中找到对应的 symbol,若是找到了,则返回它,不然,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。app
Function.prototype.Call = function (thisArg, ...args) {
//这里this为这个方法的调用者
const fn = Symbol('fn')
thisArg[fn] = this || globalThis
//经过对象调用函数,并传参
args.length ? thisArg[fn](...args) : thisArg[fn]()
//删除挂载到指定对象上的方法
delete thisArg[fn]
}
func.Call(obj) // obj undefined
func.Call(obj, 'test') // obj test
复制代码
这里不使用
arguments
对象获取传入参数。arguments
不是一个Array
,除了length属性和索引元素以外没有任何Array
属性。函数使用剩余参数
...args
能够精简代码post
bind() 函数会建立一个新的绑定函数,它包装了原函数对象。调用绑定函数一般会致使执行包装函数。ui
简单版本this
Function.prototype.Bind = function(thisArg, ...args){
let self = this;
let fBound = function(...args1){
return self.apply(thisArg, [...args, ...args1]);
}
return fBound;
}
复制代码
使用闭包保存了第一次绑定时的this值,同时使后续的绑定无效
Function.prototype.Bind = function(thisArg, ...args){
let self = this;
let fBound = function(...args1){
//若是当前this为fBound的实例,表示是执行了new,指向this,不然指向bind对象
return self.apply(this instanceof fBound ? this : thisArg, [...args, ...args1]);
}
//修改返回函数的 prototype 为绑定函数的 prototype,new出实例对象就能够继承绑定函数的原型中的成员
fBound.prototype = this.prototype;
return fBound;
}
复制代码
这里补充了绑定的函数为构造函数时的状况
function foo(age, height) {
console.log(this.name) // obj
console.log(age) // 3
console.log(height) // 2
}
const obj = {
name: 'obj',
age: 3
}
foo.Bind(obj, obj.age)(2) // 绑定bind时同时传递一个参数
复制代码
若是你收获了新知识,请给做者点个赞吧~