数组精讲
本文在这里就不讨论数组的定义以及一些方法,主要讨论的是一些数组的面试方面常常考到的问题。
首先讲一下数组去重的问题
var arr = [0, 0, 1, 2, 2, 3, 'a'];
console.log(arr);
var obj = {},
newarr = [];
Array.prototype.unique = function() {
var length = this.length;
for (var i = 0; i < length; i++) {
if (!obj.hasOwnProperty(this[i])) {
obj[this[i]] = this[i];
newarr.push(this[i]);
}
}
return newarr;
}
var uniquearr = arr.unique();
这段代码是通过给制造一个对象,然后通过是否有该键值来确定数组元素是否重复。
字符串的去重
var str = '112233rr';
var obj = {},
newstr = '';
String.prototype.unique = function() {
var length = this.length;
for (var i = 0; i < length; i++) {
if (!obj.hasOwnProperty(this[i])) {
obj[this[i]] = this[i];
newstr += this[i];
}
}
return newstr;
}
var uniquearr = str.unique();
console.log(uniquearr);
字符串的去重与数组的去重方法基本一致。
es6新提出了一种数据结构类型,叫做set数据结构,它和我们的数组类似,但是成员的值都是唯一的,没有重复的值。所以我们可以通过它来实现数组的去重。
let str = ['r', 'j', 'l', 'r'];
let strset = new Set(str);
let laststr = [...strset];
console.log(laststr);
是不是很简单啊,哈哈哈哈。。。。。。
在这里还需要搞清楚一个原理,就是push()方法的工作原理。底下这个是将对象给其附上了数组的属性与方法,主要还是理解push的工作原理
var obj = {
'2': 3,
'3': 4,
'push': Array.prototype.push,
'splice': Array.prototype.splice,
'length': 2
}
obj.push(1);
obj.push(2)
console.log(obj);
这段代码告诉我们push的真正工作原理是这样的
Array.prototype.push=function push(elem){
this[this.length]=elem;
this.length++;
}
关于apply()方法和call()方法,他们两个其实区别不大,主要的不同就是后面传递参数时不一样,apply()方法后面传递的是数组,call()方法传递的是具体的参数。
至于bind方法,他会返回一个不会执行的函数,仍然改变了this的指向。传递参数和那个call是一样的,一下代码可以实现bind方法的功能
var p = {
name: 'renjialei'
}
function Person(age, sex) {
console.log(this);
console.log(this.name);
console.log(age, sex);
}
Person.bind(p)();
//实现一个bind方法!
Function.prototype.bindy = function(context) {
var _self = this;
var args = Array.prototype.slice.call(arguments, 1); //1代表从第二个位置开始截取
return function() {
var newargs = Array.prototype.slice.call(arguments);
_self.apply(context, args.concat(newargs)); //传入两个参数,context默认代表第一个参数
}
}
Person.bindy(p, '18')('man');
在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理:
var divs = document.getElementsByTagName("div");
var div = Array.prototype.slice.call(divs);
Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换),此时将具有数组的方法。
Object.prototype.toString.call()方法
在实际开发中tostring()方法确实被继承了下来,但被自己的儿子数组给重写了方法。所以在数组上直接调用该方法会返回一个字符串。
var a = [];
console.log(Object.prototype.toString.call(a)); //[Object Array]