所以我试图创建一种方法来完全模仿
Array.prototype.map()
方法的作用,但有很多地方让我感到困惑。
我认为主要问题在于它的语法。我知道有很多不同的方法可以利用 map
方法,例如:
示例1:
假设我有一个对象数组 -
var movieList = [
{"Title" : "Inception",
"Awards" : "4 oscars",
"Language" : "English",
"imdbRating" : "8.8"
},
{"Title" : "Inception2",
"Awards" : "44 oscars",
"Language" : "English and Spanish",
"imdbRating" : "9.8"
},
{"Title" : "Interstellar",
"Awards" : "10 oscars",
"Language" : "English",
"imdbRating" : "9.5"
}
];
假设我想创建一个函数,返回一个仅包含电影标题及其 imdbRating 的对象列表。在这种情况下,我可以使用
map()
方法:
let newList = movieList.map( (current) ({'title': current['Title'],
'rating': current['imdbRating'] }) );
上面的代码行满足了我使用map方法实现目标所需的内容。但是,其他情况的语法可能有所不同
示例2:
let s = [1, 2, 3, 4];
let s2 = s.map( function(item) {
return item*2;
});
使用映射函数 s2 将返回一个数组,其中每个元素的值都是 s 数组中每个元素的值的两倍。 现在,回到这篇文章的主题,我正在解决的问题给了我这个大纲作为开始:
Array.prototype.myMap = function(callback) {
let newArray = [];
我知道,当数组调用
myMap
方法时,它会插入 2 个参数:数组和函数。但我无法理解如何将元素上每个回调函数的值具体分配给 newArray
方法中的 myMap
。特别是因为我不知道如何访问原始数组。
据我所知,我的尝试之一是荒谬的,因为我不知道如何访问数组的长度以及调用
myMap
方法的数组本身 -
Array.prototype.myMap = function(callback) {
let newArray = [];
let x = this.length();
for(let i=0; i<x; i++){
let counter = callback();
newArray.push(counter);
}
return newArray;
};
到目前为止,我理解
map()
方法的方式是,它需要 3 个参数、一个数组、一个函数以及将通过该函数放入的元素,而且我不太了解语法,无法迭代数组调用 map
方法,但在我的课程中没有任何地方教过我如何执行此操作,而且我也没有找到任何可以提供此问题解决方案的在线资源。
length
不是一个方法 - 它只是一个属性。并且您需要将 this[i]
传递给 callback
以获得正确的输出。
Array.prototype.myMap = function(callback) {
let newArray = [];
let x = this.length;
for (let i = 0; i < x; i++) {
let counter = callback(this[i]);
newArray.push(counter);
}
return newArray;
};
let arr = [1, 2, 3];
arr = arr.myMap(e => e * 2);
console.log(arr);
请注意,改变原型方法是一种非常糟糕的做法,尤其是在存在相同方法时创建新方法。 (
map
具有 myMap
的所有功能以及更多)。
map
Polyfill 的简化版本。您需要使用 length
来获取 this.length
。并将循环中的当前项、它的索引和数组本身作为参数传递给 callback
Array.prototype.myMap = function(callback, thisArg) {
const newArray = [];
const length = this.length;
for (let i = 0; i < length; i++) {
let value = callback(this[i], i, this); // call with proper arguments
newArray.push(value);
}
return newArray;
};
const arr = [1, 2, 3];
console.log(arr.myMap(a => a * 2))
注意:
map
方法也采用thisArg
作为参数。如果你想使用它,你需要 call
callback
和 thisArg
为 this
callback.call(thisArg, this[i], i, this);
像这个答案,但正确保留空项目。
Array.prototype.map = function (callback, thisArg) {
let arr = [];
const len = this.length;
for (let i = 0; i < len; i++) {
if (i in this) arr.push(callback.call(thisArg, this[i], i, this));
else arr.length++;
}
return arr;
};
在这里您可以了解更多关于 javascript 地图功能的信息: https://www.w3schools.com/jsref/jsref_map.asp
实现map方法实际上比你想象的要容易得多。这是一个非常简单的示例,它的功能与 https://www.w3schools.com/jsref/jsref_map.asp:
中的 map 方法完全相同Array.prototype.myMap = function(callback) {
arr = [];
for (var i = 0; i < this.length; i++)
arr.push(callback(this[i], i, this));
return arr;
};
//tests
var numbers2 = [1, 4, 9];
var squareRoot = numbers2.myMap(function(num) {
return Math.sqrt(num);
});
console.log(squareRoot); // [ 1, 2, 3 ]
因此,map 方法只是返回一个数组,通过在每个值上运行作为参数给出的指定函数,将其值映射到原始数组的值。
注意: 该方法跳过原始地图函数的可选参数,该参数指定
this
值
这是您的
myMap
函数的工作版本。
模仿这些方法可能会让人感到困惑的是
this
关键字在 javascript 中的工作原理。这是一篇 MDN Reference 文章。
Array.prototype.myMap = function(callback, thisArg) {
let newArray = [];
let x = this.length;
for(let i=0; i<x; i++){
let counter = callback.call(thisArg, this[i], i, this);
newArray.push(counter);
}
return newArray;
};
Array.prototype.mappy = function (callback, thisArg) {
let newArray = [];
for (let i = 0; i < this.length; i++) {
if (i in this) newArray.push(callback.call(thisArg, this[i], i, this));
else newArray.push(undefined);
}
return newArray;
};
您可以利用扩展运算符并执行以下操作:
Map.prototype.slice = function(start, end) {
return new Map([...this].slice(start, end));
};
使用中:
const testMap = new Map([["a", 1], ['b', 2], ["c", 3], ["d", 4], ["e", 5]]);
console.log(testMap); // Map(5) { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5 }
console.log(testMap.slice(0, 2)); // Map(2) { 'a' => 1, 'b' => 2 }
您绝对可以以此为基础,因为这仍然有
Array.prototype.slice()
的警告。
如果您不想使用
forEach
,也可以使用
for loop
Array.prototype.myMap = function (callback) {
let newArr = [];
this.forEach((item) => {
let elem = callback(item);
newArr.push(elem);
});
return newArr;
};
在 javascript 中创建自定义地图函数
Array.prototype.myMap = function (cb){
let temp =[];
for(let i = 0; i < this.length; i++){
temp.push(cb(this[i], i, this))
}
return temp;
};
在此自定义函数回调 cb 中,具有三个参数:当前元素、索引和实际数组。
const arr = [1, 2, 3, 4];
//using myMap
arr.myMap((num)=>num)
我关于如何使用打字稿进行递归方式的建议
Array.prototype.customMap = function customMap<T>(
callback: (element: T, index: number, array: T[], self?: T[]) => T
): T[] {
if (this.length === 0) {
return [];
}
return (([index, result]) => {
return [
callback(
this[this.length - 1 - index],
this.length - 1 - index,
this,
this
),
...result,
];
})(mapWithSize<T>(this.slice(1), callback));
};
function mapWithSize<T>(
sequence: T[],
callback: (element: T, index: number, array: T[], self?: T[]) => T
): [number, T[]] {
return [sequence.length, sequence.customMap(callback)];
}