Array.prototype.mymap = function (fn) {
// 结果数组
let results = [];
// 遍历this
for (let i = 0; i < this.length; i++) {
results.push(fn(this[i]));
}
return results;
}
var arr1 = [3, 4, 5, 6, 9];
var arr2 = arr1.mymap(item => item * 2);
console.log(arr2);
封装自己的filter方法(超级高频面试题)
Array.prototype.myfilter = function (fn) {
// 结果数组
let results = [];
// 遍历this(this就是调用myfitler的数组)
for (let i = 0; i < this.length; i++) {
if (fn(this[i])) {
results.push(this[i]);
}
}
return results;
}
封装自己的reduce方法
Array.prototype.myreduce = function (fn) {
let yiyou = this[0];
for (let i = 1; i < this.length; i++) {
yiyou = fn(yiyou, this[i]);
}
return yiyou;
};
严谨版:可以添加额外的参数,表示默认值,比如数组去重时:
let result = arr.myreduce((a, b) => a.includes(b) ? a : [...a, b], []);
Array.prototype.myreduce = function (fn, defaultValue) {
let yiyou, startIndex;
// 判断有没有传入第二个参数
if (defaultValue == undefined) {
// 没有传入第二个参数
yiyou = this[0];
// 从下标为1开始遍历
startIndex = 1;
} else {
// 传了第二个参数(默认值)
yiyou = defaultValue;
// 从下标为0开始遍历
startIndex = 0;
}
for (let i = startIndex; i < this.length; i++) {
yiyou = fn(yiyou, this[i]);
}
return yiyou;
};
用三种方法实现数组去重
方法1:reduce法:
var result = arr.reduce((a, b) => a.includes(b) ? a : [...a, b], []);
方法2:遍历法:
var results = [];
for (let i = 0; i < arr.length; i++) {
if (!results.includes(arr[i])) {
results.push(arr[i]);
}
}
console.log(results);
方法3:Set法。最最优雅的方法。
Set
是ES7中新增的一个数据类型,表示“集合“,说白了,就是不能有重复项的数组。
// Set是内置构造函数,是ES7新增的数据类型,表示“集合”。
// new的时候要传入一个数组进去,集合能够自动去重
let s = new Set([9, 3, 4, 5, 6, 3, 6]);
console.log(s);
集合可以通过[...集合]
变成数组。所以世界上最优美的去重方法:
var results = [...new Set(arr)];
请统计数组中每个字母出现的次数。
var arr = ['A', 'B', 'A', 'C', 'A', 'M', 'B', 'A', 'B'];
var arr = ['A', 'B', 'A', 'C', 'A', 'M', 'B', 'A', 'B'];
// 结果是一个对象
let o = {};
// 遍历原数组
for (let i = 0; i < arr.length; i++) {
if (arr[i] in o) {
o[arr[i]]++;
} else {
o[arr[i]] = 1;
}
}
console.log(o);
基本类型值和引用类型值
基本类型值:number、string、boolean、undefiend、null
引用类型值:array、function、object、regexp(正则表达式)、Set、Map……
面试题:基本类型值和引用类型值的区别是什么?答:有两点区别:
区别①:在进行a=b
这样的赋值语句时,基本类型值会在内存中把b
克隆一份给a
。引用类型值不可隆,直接将引用给a
,内存中a
、b
指向同一个对象;
区别②:在进行a==b
比较时,基本类型值比较值是否相同,引用类型值比较它们是否是内存中的同一个对象。
if (arr.length == 0) {
}
面试题:深克隆和浅克隆(超高频率面试题)
答:比如我们要克隆一个数组,那么语句arr2 = arr1不能实现克隆,arr2和arr1都是内存中的同一个对象。此时就可以使用arr2 = [...arr1]这样的写法实现克隆,它们是内存中的两个对象,彼此分开了。但是,只分开了内部的基本类型值,如果内部有引用类型值,它们还是内存中的同一个引用类型值。所以顾名思义,“浅克隆”。浅克隆,我知道4种方法:点点点法、slice法、Object.assign法、map法。这四种方法都能实现浅克隆。深克隆指的是能让数组、对象完全分开,无论自己内部没有没有其他引用类型值,实现深克隆的方法,就是使用递归。
浅克隆【方法1:点点点法】
let arr1 = [3, 4, 5, 6];
let arr2 = [...arr1];
console.log(arr2); // [3, 4, 5, 6]
console.log(arr1 == arr2); // false。false是好消息,因为表示arr1、arr2不是内存中的同一个数组
也能浅克隆对象
let obj1 = {a: 1, b: 2, c: 3};
let obj2 = {...obj1};
console.log(obj1); // {a: 1, b: 2, c: 3}
console.log(obj1 == obj2); // false
为什么是“浅”克隆?
答:因为它只能克隆数组中的基本类型值,而引用类型值,无法实现克隆的。"藕断丝连"。
【方法2:slice法】
var arr1 = [3, 4, 5, 6];
var arr2 = arr1.map(item => item);
var arr1 = [3, 4, 5, 6];
var arr2 = arr1.slice(0);
console.log(arr2); // [3, 4, 5, 6]
console.log(arr1 == arr2); // false
【方法3:map法】
【方法4:Object.assign()法】
Object.assign
是合并对象的。它的第一个参数会合并后面的所有参数属性,后面的参数一律不变。
var obj1 = { a: 1, b: 2 };
var obj2 = { c: 3 };
var obj3 = { d: 4 };
var obj4 = { e: 555, f: 66 };
// 合并对象
Object.assign(obj1, obj2, obj3, obj4);
console.log(obj1); // {a: 1, b: 2, c: 3, d: 4, e: 555, f: 66};
console.log(obj2); // {c: 3};
console.log(obj3); // {d: 4};
console.log(obj4); // {e: 555, f: 66};
可以妙用Object.assign
达到浅克隆的目的:
var obj1 = { a: 3, b: 4 };
var obj2 = Object.assign({}, obj1); // 将obj1合并到空对象上
console.log(obj1 == obj2); // false。好消息,说明分开了
console.log(obj2); // { a: 3, b: 4 }
深克隆
function deepClone(o) {
if (Array.isArray(o)) {
// 数组
return o.map(item => deepClone(item));
} else if (typeof o == 'object') {
// 对象。
// 准备一个空对象,然后遍历对象o,把属性都誊抄上去,但是誊抄的值,都要深克隆一下
let resultobj = {};
for (let k in o) {
resultobj[k] = deepClone(o[k]);
}
return resultobj;
} else {
return o;
}
}
let arr1 = [3, 4, 5, 6, { m: [7, 8] }];
let arr2 = deepClone(arr1);
console.log(arr2); // [3, 4, 5, 6, { m: [7, 8] }]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)