一、call()方法
- call()方法调用一个对象,简单理解为调用函数的方式,但是它可以改变函数的this指向
- fun.call(thisArg,arg1,arg2,.....)
- thisArg: 在 fun 函数运行时指定的 this 值
- arg1,arg2: 传递的其他参数
- 返回值就是函数的返回值,因为它就是调用函数
- 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承
1、call()的经典用法
<body>
<script>
// 改变函数内this指向 js提供了三种方法 call() apply() bind()
// 1. call()
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
};
fn.call(o, 1, 2);
// call 第一个可以调用函数 第二个可以改变函数内的this 指向
// call 的主要作用可以实现继承
function Father(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname, age, sex) {
Father.call(this, uname, age, sex);
}
var son = new Son('刘德华', 18, '男');
console.log(son);
</script>
</body>
二、call()里面的参数解读
var arr = [1,2,3,4]
function fn(i){
return i>2
}
for(var i in arr){
console.log(fn.call(null,arr[i]));//false false true true
}
我们首先来看一下这句话
fn.call(null,arr[i])
thisArg: 在 fun 函数运行时指定的 this 值
第一个参数的null就是不指定this的指向,所以将null改为fn不影响最终结果。
arg1,arg2: 传递的其他参数,这些参数会传给call方法的调用者,当调用者的实参。
第二个参数arr[i]就是从数组arr中循环遍历的一个具体数组项,这个arr[i]将会当成参数传给fn,也就是后面会去比较的i>2。
三、例子
请补全JavaScript代码,要求实现Array.filter函数的功能且该新函数命名为"_filter"。示例
输入:[1,2]._filter(i => i>1)
输出:[2]
题目分析:
Array.prototype.filter() - JavaScript | MDN
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter以上为MDN数组内置方法filter()的具体文档。
(1)本题需要扩展Array的内置对象方法:
Array.prototype._filter = function(fn){
//1、判断fn是否为方法
if (typeof fn !== 'function') {
throw new TypeError('should be function')
}
}
根据题目要求,实现一个仿Array.filter功能的"Array._filter"函数,该函数创建一个新数组,该数组包含通过函数参数条件的所有元素,核心步骤有:
- 判断参数是否为函数,如果不是则直接返回
- 创建一个空数组用于承载新的内容
- 循环遍历数组中的每个值,分别调用函数参数,将满足判断条件的元素添加进空数组中
- 返回新的数组
// 补全代码{
Array.prototype._filter = function(fn){
//1、判断fn是否为方法
if (typeof fn !== 'function') {
throw new TypeError('should be function')
}
//2、创建一个新数组接收过滤后的值
const newArray = []
//3、循环遍历数组中的每个值,分别调用函数参数,将满足判断条件的元素添加进空数组中
//(1)拿到数组,此处的this为函数的调用者Array
let arr = this
//(2)将满足判断条件的元素添加进空数组中
for(var i=0; i<arr.length; i++){
let result = fn.call(arguments[0], arr[i], i, arr);//将arguments[0]改为null亦可
result && newArray.push(arr[i])
}
console.log(newArray);//[2]
return newArray;
}
var arr = [1,2]
arr._filter(i => i>1)
4、实现call函数
- call()方法调用一个对象,简单理解为调用函数的方式,但是它可以改变函数的this指向
- fun.call(thisArg,arg1,arg2,.....)
- thisArg: 在 fun 函数运行时指定的 this 值
- arg1,arg2: 传递的其他参数
- 返回值就是函数的返回值,因为它就是调用函数
- 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承
//1.获取调用该方法的对象,将this赋给对象参数,可以任意命名;即把Product构造函数当作Food的一个属性
//2.通过该对象参数临时调用函数并返回结果;返回的是Product的返回值
//3.最后删除对象参数的临时函数属性
Function.prototype._call = function (obj, ...args) {
// console.log(obj);//Food方法
// console.log(args);//['包子',12]
obj.fn = this;//this为Product方法,现在把Product方法内置为Food的方法
var res = obj.fn(...args);//调用传过来的参数['包子',12]
console.log(res);//1 返回call调用者的返回值,若没有返回值,则返回undifined
delete obj.fn;//删除掉Product方法
return res;//同时接收函数的返回值,没有返回值则返回undefined
}
function Product(name,price){
this.name = name;
this.price = price;
return 1;
}
function Food(name,price){
Product._call(this,name,price);// Product._call(Food,'包子',12);
this.category = 'food';
}
var bz = new Food('包子',12);
console.log(bz);//Food {name: '包子', price: 12, category: 'food'}
call函数就是把调用者的代码再用新的this指向的值运行一遍,其他的参数是传递的参数。返回的是调用者的返回值。
变相的实现了继承的功能。
Function.prototype._call = function (obj, ...args) {
// console.log(obj);//Food方法
// console.log(args);//['包子',12]
obj.fn = this;//this为Product方法,现在把Product方法内置为Food的方法
var res = obj.fn(...args);//调用传过来的参数['包子',12]
console.log(res);//1 返回call调用者的返回值,若没有返回值,则返回undifined
delete obj.fn;//删除掉Product方法
return res;//同时接收函数的返回值,没有返回值则返回undefined
}
const o1 = {
name: 'z',
fn: function() {return this.name}
};
const o2 = {name: 'g'};
const result = o1.fn._call(o2);
console.log(result === 'g')//true
这篇博客详细介绍了JavaScript中的call()方法,包括其作用、参数解释和经典用法。call()方法允许指定函数的this值,并按需传递参数,常用于改变函数的上下文和实现继承。文中还通过实现Array.prototype.filter的功能来演示了call()的实际运用。

885

被折叠的 条评论
为什么被折叠?



