一邊學習前端,一邊經過博客的形式本身總結一些東西,固然也但願幫助一些和我同樣開始學前端的小夥伴。前端
若是出現錯誤,請在評論中指出,我也好本身糾正本身的錯誤node
author: thomaszhou編程
數組的內置方法應用
判斷是不是數組類型
不少時候咱們須要對JavaScript中數據類型( Function、String、Number、Undefined、Boolean和Object
)作判斷。在JavaScript中提供了typeof
操做符能夠對這些經常使用的數據類型作判斷。但要使用typeof
來判斷數據是否是一個數組,就不起做用了數組
console.log(typeof function () {return;}); // function
console.log(typeof "a"); // string
console.log(typeof 123); // number
console.log(typeof a); //undefined
console.log(typeof true); // boolean
console.log(typeof NaN); // number
console.log(typeof !NaN); //boolean
console.log(typeof {name:"leo",age: "37"}); // object
console.log(typeof ["leo","37"]); // object
console.log(typeof null); // object
複製代碼
var arr = [1,2,3,45];
function isArray(obj){
return Array.isArray(obj);
}
alert(isArray(arr));
複製代碼
ECMAScript 5 還有着很是大的兼容性,因此咱們並不能完美的使用原生判斷,當使用ie6/7/8的時候就會出現問題。瀏覽器
constructor
屬性返回對建立此對象的函數的引用,使用此屬性能夠檢測數組類型instanceof
。 instanceof用來判斷某個構造函數的prototype
是否存在於被檢測對象的原型鏈裏。也就是判斷前面的對象是不是後者對象的類或者實例。var arr = [1,2,3,45];
console.log(arr.constructor === Array);
console.log(arr instanceof Array);
複製代碼
var is_array = function(obj){
return Object.prototype.toString.call(obj) === '[object Array]';
};
alert(is_array(arr));
複製代碼
使用Object.prototype.toString
方法來檢測對象類型。toString將返回[object type]
type
爲對象類型。下面是對象檢測顯示的結果。bash
var toString = Object.prototype.toString;
console.log(toString.call(dd));//[object Function]
console.log(toString.call(new Object));//[object Object]
console.log(toString.call(new Array));//[object Array]
console.log(toString.call(new Date));//[object Date]
console.log(toString.call(new String));//[object String]
console.log(toString.call(Math));//[object Math]
console.log(toString.call(undefined));//[object Undefined]
console.log(toString.call(null));//[object Null]
複製代碼
所以咱們能夠利用對象的Object.prototype.toString方法檢測對象是否爲數組。在frame下也經過。app
最佳檢測方法就是,無論原生isArray是否可用,都回歸到object.prototype.toString的檢測上。dom
Object.prototype.toString
的行爲:首先,取得對象的一個內部屬性[[Class]]
,而後依據這個屬性,返回一個相似於"[object Array]"的字符串做爲結果(看過ECMA標準的應該都知道,[[]]
用來表示語言內部用到的、外部不可直接訪問的屬性,稱爲「內部屬性」)。利用這 個方法,再配合call,咱們能夠取得任何對象的內部屬性[[Class]],而後把類型檢測轉化爲字符串比較,以達到咱們的目的。call
改變toString的this引用爲待檢測的對象,返回此對象的字符串表示,而後對比此字符串是不是[object Array],以判斷其是不是Array的實例。爲何不直接o.toString()?嗯,雖然Array繼承自Object,也會有toString方法,可是這個方法有可能會被改寫而達不到咱們的要求,而Object.prototype則是老虎的屁股,不多有人敢去碰它的,因此能必定程度保證其「純潔性」:)JavaScript 標準文檔中定義: [[Class]] 的值只多是下面字符串中的一個:Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String。
函數
var isArray = function () {
if (Array.isArray) {
return Array.isArray;
}
//下面語法不明白
var objectToStringFn = Object.prototype.toString, arrayToStringResult = objectToStringFn.call([]);
return function (subject) {
return objectToStringFn.call(subject) === arrayToStringResult;
};
}();
alert(isArray(arr));// true
複製代碼
複製數組
咱們都知道數組是引用類型數據。這裏使用slice,map複製一個數組,原數組不受影響。性能
let list1 = [1, 2, 3, 4];
let newList = list1.slice();//推薦slice
list1.push(5); // [1,2,3,4,5]
console.log(newList); //[1,2,3,4]
console.log(list1); //[1, 2, 3, 4, 5]
let list2 = [5,6,7,8];
let newList2 = list2.concat();
newList2.push(9); //
console.log(newList2); //[5, 6, 7, 8, 9]
console.log(list2); //[1, 2, 3, 4, 5]
複製代碼
轉換成數組
類數組(NodeList)轉數組(Array),函數參數轉數組
getElementsByClassName獲取的dom元素的數據類型爲HTMLCollection,雖然相似於數組能夠遍歷,可是該數據類型不存在數組中用於操做數組的方法,經過y如下方法轉換後,就可使用數組的內置方法
//返回的不是真正的Array(你沒法使用filter、map、reduce等方法)
const nodeList = document.querySelectorAll('div');
// 方法1: 使用Array.from
const arrayList1 = Array.from(nodeList);
// 方法2: 使用slice
const arrayList2 = Array.prototype.slice.call(nodeList);
// 方法3: 使用ES6語法糖
const arrayList3 = [...nodeList];
複製代碼
函數參數轉數組 將函數參數轉數組,利用arguments僞數組形式,再用slice拷貝爲新數組。
function argsParam() {
//arguments僞數組形式,再用slice拷貝爲新數組
return Array.prototype.slice.call(arguments);
}
console.log(argsParam(1,2,3,4)); //[1, 2, 3, 4]
複製代碼
Array.prototype.slice = function(start,end){
var result = new Array();
start = start || 0;
end = end || this.length; //this指向調用的對象,當用了call後,可以改變this的指向,也就是指向傳進來的對象,這是關鍵
for(var i = start; i < end; i++){
result.push(this[i]);
}
return result;
}
複製代碼
var a = {length:2, 0:'zero', 1: 'first'};
console.log(Array.prototype.slice.call(a)); // ["zero", "first"]
var b = {length:3, 0:'zero', 1: 'first', 2 : 'zero'};
console.log(Array.prototype.slice.call(b)); // ["zero", "first", "zero"]
var c = {length:3, 2 : 'zero'};
console.log(Array.prototype.slice.call(c)); // [empty, empty , "zero"]
複製代碼
重複n個字符
/**
@params
num: 重複次數
str: 重複字符串
**/
function repeatStr(num, str) {
return new Array(num+1).join(str);
}
console.log(repeatStr(5, 's'));//sssss
複製代碼
建立n乘n二位矩陣
建立n乘n二維矩陣,並初始化數據 使用Array對象傳入數組length參數,調用fill再用map循環fill替換對應的值返回一個新數組
/**
@params
num: 矩陣次數
str: 矩陣數組中的值,因爲fill函數替換因此值都是一致的
**/
function arrayMatrix(num, matrixStr) {
return Array(num).fill(null).map(() => Array(num).fill(matrixStr));
}
// ["a", "a", "a", "a"] ["a", "a", "a", "a"] ["a", "a", "a", "a"] ["a", "a", "a", "a"]
console.log(arrayMatrix(4, 'a'));
複製代碼
數組去重
!!! 方法12345對於數字1和字符串1這類的問題,是沒法去重的,可是方法6能夠解決這個問題,可是也會致使須要設置最後是留下字符串的1仍是數字1
function unique1(array){
var n = []; //一個新的臨時數組
//遍歷當前數組
for(var i = 0; i < array.length; i++){
//若是當前數組的第i已經保存進了臨時數組,那麼跳過,
//不然把當前項push到臨時數組裏面
if (n.indexOf(array[i]) == -1)
n.push(array[i]);
}
return n;
}
複製代碼
經過unique1.apply(arr)或unique1.call(arr)調用,爲何?
unction unique3(arr){
var n = [];
n.push(arr[0]);
len = arr.length;
//從第二項開始遍歷
for(var i = 1; i < len; i++) {
//若是當前數組的第i項在當前數組中第一次出現的位置不是i,
//那麼表示第i項是重複的,忽略掉。不然存入結果數組
if (arr.indexOf(arr[i]) == i) {
n.push(arr[i]);
}
}
return n;
}
console.log(unique3(arr));
複製代碼
function unique4(array){
array.sort();
var re=[array[0]];
for(var i = 1; i < array.length; i++){
if( array[i] !== re[re.length-1]){
re.push(array[i]);
}
}
return re;
}
複製代碼
// use 'strict';
var arr = ['1',1,2,3,4,4,45,65,'b','a','b'];
function unique4 (arr) {
var newArr = [],// 構建一個新數組存放結果
object = {};
len = arr.length;
// for循環時,每次取出一個元素與對象進行對比
// 若是這個元素不重複,則將它存放到結果數中
// 同時把這個元素的內容做爲對象的一個屬性,並賦值爲1,
// 存入到第2步創建的對象中
for (var i = 0; i < len; i++) {
// 檢測在object對象中是否包含遍歷到的元素的值
if (!object[typeof arr[i] + arr[i]]) {
// 若是不包含,將存入對象的元素的值推入到結果數組中
object[typeof arr[i] + arr[i]] = 1
//存入object對象中該屬性名的值設置爲1
newArr.push(arr[i]);
}
}
// console.log(object);
return newArr;
}
console.log(unique4(arr));
複製代碼
test:
var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique3(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5, "1", "2"]
複製代碼
不一樣的鍵可能會被誤認爲同樣;例如: a[1]、a["1"] 。這種方法所費時間:621ms。這種方法所費時間是最短,但就是佔用內存大一些
function unique4 (arr) {
var newArr = [],
object = {};
len = arr.length;
for (var i = 0; i < len; i++) {
if (!object[arr[i]]) {
object[arr[i]] = 1;
newArr.push(arr[i]);
}
}
console.log(object);
return newArr;
}
console.log(unique4(arr));
複製代碼
注意set返回的也是一個不重複的類數組形式要使用Array.from或者別的方法方法轉成數組形式
function unique (arr) {
return Array.from(new Set(arr))
}
或者:
const unique = arr => [...new Set(arr)];
複製代碼
用 a 和 b 的全部值建立一個 Set 並轉換成一個數組。
const union = (a, b) => Array.from(new Set([...a, ...b]));
// union([1,2,3], [4,3,2]) -> [1,2,3,4]
複製代碼
過濾數組中的非惟一值
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// console.log(filterNonUnique([1,2,2,3,4,4,5])); // [1,3,5]
複製代碼