//判断arr是否为一个数组,返回一个bool值
首先javascript有5大基本数据类型:Undefined,Null,Boolean,Number、String(双无BNS)和Symbol (ECMAScript 6 新定义)
还有一个引用数据类型:Object,它包括以下三大类:
Native Object(原生对象): ECMAScript本身自带的对象,是在脚本运行环境中程序员创建来使用的,包括:Object(基础类型)、Array、Date、Function、RegExp;另外还包括三个基本包装类型:Boolean、Number、String,有了它们三个我们可以将基本类型值当作对象来访问(使用他们的属性和方法)。
Build-in Object(内置对象): JavaScript语言提供的不依赖于执行宿主的内建对象,如:Global、Math;内建对象都是Native Object。
-
Host Object(宿主对象):JavaScript语言提供的任何依赖于宿主环境的对象,所有非Native Object的对象都是宿主对象,如:IE中的window,WScript中的wscript实例,以及任何用户创建的类。
所以我们判断的数组(Array)就是复杂数据类型Object中的其中一类,我们需要使用Object自带的方法来判断它——
首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于"[object Array]"的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。
function isArray (arr) { return Object.prototype.toString.call(arr) === '[Object Array]';}
call改变toString的this引用为待检测的对象,返回此对象的字符串表示,然后对比此字符串是否是'[object Array]',以判断其是否是Array的实例。也许你要问了,为什么不直接o.toString()?嗯,虽然Array继承自Object,也会有toString方法,但是这个方法有可能会被改写而达不到我们的要求,而Object.prototype则是老虎的屁股,很少有人敢去碰它的,所以能一定程度保证其“纯洁性”。
//判断fn是否为一个函数,返回一个bool值。
function isFunction (fn) { return (typeof fn === 'function');}// orfunction isFunction (fn) { return Object.prototype.toString.call(arr) === '[Object Function]';}
// 使用递归来实现一个深度克隆,可以复制一个目标对象,返回一个完整拷贝
// 被复制的对象类型会被限制为数字、字符串、布尔、日期、数组、Object对象。不会包含函数、正则对象等思路如下
题目考的主要是有些对象的使用=直接赋值,并不是真正的复制,而是将一个新的变量指向了当前对象,共享同一个地址。在修改原对象时,新对象也会跟着改变。
经过测试,数字、字符串、布尔、日期、可以直接赋值,修改不会产生影响。所以就思考了在使用typeof值为对象或者是原始类型时的情况。且对象类型为Date对象时,也使用直接赋值的方式。
再考虑对象类型为Array或者Object的情况。对于结果声明其类型。
接着往下走,在遍历对象时,只考虑其自身的属性,而不考虑继承来属性。若其自身值还是对象,那么 就递归调用,进一步解析、赋值,否则直接赋值。
function cloneObject(src) { var result ;//返回的复制后的结果。 if (typeof(src)==="object"){ //对象为日期对象时也直接赋值。 if(Object.prototype.toString.call(src)==="[object Date]"){ result = src; }else{ //判断对象的类型是Array还是Object,结果类型更改。 result = (Object.prototype.toString.call(src)==="[object Array]")? [] : {}; for (var i in src){ if (src.hasOwnProperty(i)) { //排除继承属性 if (typeof src[i] === "object") { result[i] = cloneObject(src[i]); //递归赋值 } else { result[i] = src[i]; //直接赋值 } } } } }else{ //对于原始类型直接赋值。 result = src; } return result;}
// 对数组进行去重操作,只考虑数组中元素为数字或字符串,返回一个去重后的数组
思路如下:
新建一下新数组
循环原数组
判断新数组内元素,原数组是否含有.含有则跳过
返回新数组.
function uniqArray(arr) { // your implement var result = []; //创建一个新数组。 for (var i = 0, l = arr.length; i < l; i++) { if (result.indexOf(arr[i]) === -1) { //查找是否已经含有该元素 result.push(arr[i]); //添加到新数组 } } return result; //返回新数组}
// 实现一个简单的trim函数,用于去除一个字符串,头部和尾部的空白字符
// 对字符串头尾进行空格字符的去除、包括全角半角空格、Tab等,返回一个字符串// 尝试使用一行简洁的正则表达式完成该题目//1.字符串查找//这里就是利用两个循环,找到头尾第一个不是空格且不是tab符的元素。记录它们的索引,之后截取字符串。function simpleTrim(str) { // your implement var result = ""; for (var i = 0, il = str.length; i < il; i++) { //从头查找 if (str[i] != " " && str[i] != "\t") { break; //查找到第一个不为空格及tab符的元素 } } for (var j = str.length - 1; j >= 0; j--) { //从尾查找 if (str[j] != " " && str[j] != "\t") { break; } } result = str.slice(i, j + 1); //截取需要的字符串。 return result;}//2.正则function trim(str) { // your implement var result = ""; result = str.replace(/^\s+|\s+$/g, ""); //使用正则进行字符串替换 return result;}
// 实现一个遍历数组的方法,针对数组中每一个元素执行fn函数,并将数组索引和元素作为参数传递
function each(arr, fn) { // your implement for (var i = 0, l = arr.length; i < l; i++) {//遍历传参 fn(arr[i], i); }}
// 获取一个对象里面第一层元素的数量,返回一个整数
//使用for in遍历时,直接获取到的就是第一层的结果//排除继承来的属性,使用外部变量保存循环次数function getObjectLength(obj) { var count = 0; for (var i in obj) { if (obj.hasOwnProperty(i)) { count++; } } return count;}