JavaScript 数组作业
1、封装一个type方法,要求完全分辩出来每一个要传进去的数据的类型
要求完全分辩出来每一个要传进去的数据的类型
思路:
1). 先给类型分两类,"原始值"、"引用值"
2). 区分引用值(原始直就那几种,接通过typeof就能返回,引用值还得细分)
typeof判断之后,会出现两种结果
(1) 原始值 String、Number、Boolen
(2) 引用值 objiec、undefined、function
步骤:
01/
null是漏掉的,没什么能判断null,nul的门类里就它自己,所以一开始就把null判断出来
function type(target){ if(target === null){ return "null"; } } console.log(type(null)); // null
02/
判断一下function函数,把函数这事清了在说其他的
function type(target){ if(target === null){ return "null"; } if(typeof(target) == 'function'){ // 这里判断函数 return 'function'; }else if(typeof(target) == 'object'){ } } var demo = function(){} console.log(type(demo)); // function
03/
如果等于object,对象有哪几种类型?
function type(target){ if(target === null){ return "null"; } if(typeof(target) == 'function'){ return 'function'; }else if(typeof(target) == 'object'){ // 如果等于object,对象有哪几种类型? // 1.数组 // 2.对象 // 3.包装类 } }
04/
通过object.pototype.toString()判断,把这几种情况的结果保存一个数组
/*--------------------------------------- var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } ---------------------------------------*/ function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'function'){ return 'function'; }else if(typeof(target) == 'object'){ // 如果等于object,有哪几种类型 // 1.数组 // 2.对象 // 3.包装类 } }
05/
是对象的,通过Object.prototype.toString来判断,是什么类型对象?
function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'function'){ return 'function'; }else if(typeof(target) == 'object'){ var str = Object.pototype.toString.call(target); // 走到这里说明是对象,既然是对象,看看是什么类型对象。 return template[str]; // 无非就是template里面的五种 }else{ } }
06/
引用值解决了,剩下的就是原始值了
function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'function'){ return 'function'; }else if(typeof(target) == 'object'){ var str = Object.pototype.toString.call(target); return template[str]; }else{ return typeof target; // 剩下的原始值在这里区分不同类型 } }
07/
简化代码
function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'function'){ // 1.不用单独判断function return 'function'; }else if(typeof(target) == 'object'){ var str = Object.prototype.toString.call(target); return template[str]; }else{ return typeof target; // 2. function直接走原始值这也行。 } }
测试一下
function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'object'){ var str = Object.prototype.toString.call(target); return template[str]; }else{ return typeof target; } } var t = ''; // t = function fn(){}; // 'function' // t = null; // null // t = 123; // number // t = 'abc'; // string // t = true; // boolean // t = new String('abc'); // string - object // t = new Number(123); // number - object // t = null; // null // t = []; // array // t = undefined; // undefined // t = new Boolean(true);// boolean - object // t = true; console.log(type(t));
继续简化代码,两次求了typeof(target)可以提前拿出来,typeof一次就行
/*** function type(target){ var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(typeof(target) == 'object'){ // 第一次 tpyeof(target) var str = Object.prototype.toString.call(target); return template[str]; }else{ return typeof target; // 第二次 tpyeof(target) } } ***/ function type(target){ var ret = typeof(target); // 提取出来,在这里typeof一遍 var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ return "null"; } if(ret == 'object'){ var str = Object.prototype.toString.call(target); return template[str]; }else{ return ret; } } function type(target){ var ret = typeof(target); var template = { "[object Array]" : "array", "[object Object]" : "object", "[object Number]" : "number - object", "[object Boolean]" : "boolean - object", "[object String]" : "string - object" } if(target === null){ // 把if连一起 return "null"; }else if(ret == 'object'){ var str = Object.prototype.toString.call(target); // 这行小方法,可以提取出来 return template[str]; }else{ return ret; } } var t = ''; // t = function fn(){}; // 'function' // t = null; // null // t = 123; // number // t = 'abc'; // string // t = true; // boolean t = new String('abc'); // string - object // t = new Number(123); // number - object // t = null; // null // t = []; // array // t = undefined; // undefined // t = new Boolean(true); // t = true; console.log(type(t)); // string - object
2、数组去重
在原型链上写数组去重 Array.pototype.unique = function(){}
var arr = [1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,'a','a','b','c','d']; Array.pototype.unique = function(){ }
写一个对象obj,把数组arr的每一位当做对象的属性名,让数组的第一位当做obj对象的属性名,属性值随意写啥都行。
下一次在让数组的第二位"1",同样当做obj对象的属性名,看看"obj[1]"有没有属性值?如果有属性值,说明这个属性名存在了,存在我们就不管了,没有我们在加。
最后这个对象构建完之后,只需把他的属性名取出来就去重了。
var arr = [1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,'a','a','b','c','d']; var obj = { "1" : "abc" }
数组去重,我们利用对象的特性,对象同一个属性名不可能出现两次
1). 对象obj.[arr[0]]代表数组arr[0]位的值1,判断对象obj.1有没有值?
没有返回undefined,没有给这个undefined填一个属性名,值随意填就为了给这个占位置
2). 下一步再看obj.[arr[1]],对象obj[1]有值是abc,有值就不给对象填了,填也填不进去了
3). 依次判断数组后面的
数组去重,利用对象同一个属性名不可能出现两次的特性,把数组的属性值当做对象的属性名,填到对象里面去,通过这样一个特性来给数组去重,这叫哈希hash的方式
Array.prototype.unique = function () { var temp = {}, // 定义一个对象,为了去比对,对象名字temp临时的意思 arr = [], // 去重完的属性放到一个新的数组里面,返回新数组 len = this.length; // 把this.length取到变量len里面,因为每一圈都要执行这个,把值len放到循环,循环就少了一步运算 for(var i = 0; len > i; i++) { // 循环把数组里面的每一位都取出来 if(!temp[this[i]]){ // 判断取出来的值是undefined我们才操作。所以我们取反为true,在进行里面的操作。 temp[this[i]] = 'abc'; arr.push(this[i]); // 能走到这里面的值都是没经过重复的值。把值push到上面构建好的空数组 } } return arr; } var arr = [1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,'a','a','b','b','b','c','c','d','d']; var newArr = arr.unique(); console.log(newArr); // [1, 2, 3, 4, 5, "a", "b", "c", "d"]
改一下对象属性值
Array.prototype.unique = function () { var temp = {}, arr = [], len = this.length; for(var i = 0; len > i; i++) { if(!temp[this[i]]){ temp[this[i]] = 'abc'; // 这里换一个高端的写法temp[this[i]] = this[i]行不行?反正就想让属性名有一个属性值,既然属性值随意,随意成this[i]行不行? arr.push(this[i]); } } return arr; } var arr = [1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,'a','a','b','b','b','c','c','d','d']; var newArr = arr.unique(); console.log(newArr); // [1, 2, 3, 4, 5, "a", "b", "c", "d"]
举一个特殊的例子,在数组里加几个数字 0
Array.prototype.unique = function () { var temp = {}, arr = [], len = this.length; for(var i = 0; len > i; i++) { if(!temp[this[i]]){ temp[this[i]] = this[i]; // 这里换一个高端的写法temp[this[i]] = this[i]行不行?反正就想让属性名有一个属性值,既然属性值随意,随意成this[i]行不行? arr.push(this[i]); } } return arr; } var arr = [1,1,1,1,2,2,2,2,3,3,3,4,4,4,5,5,5,0,0,'a','a','b','b','b','c','c','d','d',0,0]; // 数组里加两个数字 0 var newArr = arr.unique(); console.log(newArr); // [1, 2, 3, 4, 5, 0, 0, "a", "b", "c", "d", 0, 0]
为什么数字0没有去重?
temp = { 0 : 0 } if(!temp[0]){ // if判断里面,判断的是0。第二次在if判断,非0还是true,还是走判断了,就连续把0赋到数组里面去,就达不到去重的效果 }