call
传入一个指定的对象和若干指定的参数的前提下调用指定对象的属性和方法
var obj = {
name : 'harry'
}
function getName () {
console.log(this.name);
}
getName.call(obj) //harry
模拟实现,第一步
- 给对象添加方法
- 执行方法
- 删除方法
//以上代码相当于给obj添加了getName方法并调用它
var obj = {
name : 'harry',
getName: function () {
console.log(this.name);
}
}
obj.getName() //harry
//但同时给obj添加了一个属性方法,我们可以删除它
delete obj.getName
Function.prototype.myCall = function (context) {
//判断有没有传入context,如果没有就将其设为window
var context = context || window
context.fn = this
context.fn()
delete context.fn
}
第二步,call还可以传入不定数目的参数
- 从 Arguments 对象中取值,取出第二个到最后一个参数,然后放到一个数组里
- 使用slice方法,获取参数
Function.prototype.myCall = function (context) {
//判断有没有传入context,如果没有就将其设为window
var context = context || window
context.fn = this
let args = [...arguments].slice(1)
context.fn(...args)
delete context.fn
}
第三步,call可以有返回值
var obj = {
value: 1
}
function bar(name) {
console.log(this.value);
return {
value : this.value,
name
}
}
let res = bar.call(obj, 'harry')
console.log(res); //{value: 1, name: 'harry'}
补全代码
Function.prototype.myCall = function (context) {
//判断有没有传入context,如果没有就将其设为window
var context = context || window
context.fn = this
let args = [...arguments].slice(1),
res = null
res = context.fn(...args)
delete context.fn
return res
}
测试代码
var foo = {
value : 1,
}
function bar (name, age) {
this.name = name
this.age = age
console.log(this.value);
console.log(`我是${this.name},我${this.age}岁了`);
}
Function.prototype.myCall = function (context) {
var context = context || window
context.fn = this
let args = [...arguments].slice(1),
res = null
res = eval(context.fn(...args))
delete context.fn
return res
}
let res = bar.myCall(foo, 'potter', 12) //1 我是potter,我12岁了
apply
apply和call相似,apply参数接受一个指定的对象和数组
Function.prototype.myApply = function (context) {
//判断有没有传入context,如果没有就将其设为window
var context = context || window
context.fn = this
//判断有没有传入第二个参数数组
if (arguments[1]) {
res = context.fn(...arguments[1])
} else {
res = context.fn()
}
delete context.fn
return res
}
var obj = {
value : 1
}
function bar (name, age) {
this.name = name
this.age = age
console.log(this.value);
console.log(`我是${this.name},我${this.age}岁了`);
}
bar.apply(obj, ['potter', 13])