原生js实现call
call方法:
function func() {
console.log(this.age)
}
let obj = {
age:18
}
func.call(obj); //18
- 改变了this指向
- 传递了参数列表
1.改变了this指向
//依赖原理:方法调用模式(谁调用,this指向谁)
function func() {
console.log(this.age);
}
let obj = { age:18 }
obj.fn = func;
obj.fn() //18 //func中this指向obj
delete obj.fn
console.log(obj);
//需求:封装一个方法mycall,实现调用func,且func的this指向obj
//func.mycall(obj)
function func() {
console.log(this);
}
let obj = { name: 'zs' }
Function.prototype.mycall = function (obj) {
//1.func.mycall()
// console.log(this); //func
//2.传参obj
//实现:this指向obj
obj.fn = this
obj.fn() //func中的this,指向obj
//1.既调用了func,又改变了this指向
delete obj.fn
}
func.mycall(obj)
2.传递参数列表
let People = {
language : '...',
speak : function (say) {
console.log(say +'-'+ this.language)
}
}
People.speak('people'); // 结果:people...
let Chinese = {
language : '中国话',
}
//将this的指向改变成了Chinese
People.speak.call(Chinese, 'chinese'); //结果:chinese-中国话
//需求:实现传参
function func(a,b) {
console.log(a,b);
}
let obj = { name: 'zs' }
Function.prototype.mycall = function (obj) {
let args = []
//第一种方式:eval()--------------------------------
for (var i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']')
}
obj.fn = this
eval('obj.fn('+args+')')
//eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。
//第二种方式:...(ES6语法)--------------------------------
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i])
}
obj.fn = this
obj.fn(...args)
//...将数组转化为参数序列
delete obj.fn
}
func.mycall(obj, 'aa', '111')
注意 : 怎么把数组args转换成多个参数传递给函数 ?
- eval(‘obj.fn(’+ args +’)’)
- obj.fn.apply(obj, args)
- obj.fn(…args); //es6解构语法**(推荐)*