DOM对象和类数组对象的探索

实践是最好的老师,愿你的每一天都在学习中成长

本文的主题是DOM对象和DOM数组,但是在正文开始之前,需要一点点铺垫

在没有遇到这样的场景之前,我一直不清楚DOM对象和普通对象的区别,可是当我们遇见了需要处理的场景,就需要为了解决问题而做一些实践,深入了解一下其中的缘由。

前言

判断对象是否为空的方法
  • JSON.stringify()
judgeEmptyObjectByJSON: function (obj) {
      return JSON.stringify(obj) === '{}';
 }

console.log(judgeEmptyObjectByJSON({}));
//true

console.log(judgeEmptyObjectByJSON({name:'andy'}));
//false

  • Object.keys()
judgeEmptyObjectByObjectKeys: function (obj) {

    return Object.keys(obj).length === 0;
}

console.log(this.judgeEmptyObjectByObjectKeys({}));
//true

console.log(this.judgeEmptyObjectByObjectKeys({name:'andy'}));
//false
  • $.isEmptyObject()
    在JQuery的源码中,isEmptyObject()函数时是这样写的:
    JQuery的源码isEmptyObject()

原理是通过for...in遍历key

judgeEmptyObjectByForIn: function (obj) {

      for(let name in obj){
        return false;
      }

      return true;
}

console.log(this.judgeEmptyObjectByForIn({}));
//true

console.log(this.judgeEmptyObjectByForIn({name:'andy'}));
//false

正文

通过操作DOM元素拿到的Object和Array的特殊使用方法:

关于Object
  • 场景
    在前端做上传文件,提交之前拿到和上传的文件有关的对象,按照需求对此对象进行判空处理。

  • 实践
    上传文件时,我们需要用到的基本html元素如下:

<div class="main-content">
    <input type="file" class="input-file">
</div>

然后通过JQuery的选择器拿到相应的元素,为它绑定函数

 let fileInput = $('.input-file');
 fileInput.bind('change', this.updateFile);

在updateFile()函数中取到和file有关的对象,它里面存着和上传的文件有关的信息:

updateFile: function () {
      let file = $('.input-file');
      this.fileObject = file[0].files[0];

      console.log(this.fileObject);
      console.log(typeof this.fileObject);
 }

然后在控制台看见打出的信息如图:


file对象

首先可以确定这是一个对象,而且对象中相关的字段都是肉眼可见,现在有需求描述:对此文件对象作判空处理,如果为空,则做其他处理。

按照之前总结过的对象判空方法,我们先操作一下看结果:

updateFile: function () {
      let file = $('.input-file');
      this.fileObject = file[0].files[0];
      
      console.log(this.fileObject);
      console.log(typeof this.fileObject);

      let isEmpty = JSON.stringify(this.fileObject) === '{}';
      console.log(isEmpty);
},

判断file对象是否为空

好了,神奇的事情发生了,控制台告诉我们,此时的我们拿到的file对象是空的!!!
很奇妙吧,当然一开始不知道是为什么,查了一些解决办法,也明白了一点:

通过$()取出来的对象,是JQuery包装过的DOM对象,它的本质是和普通的数据对象是一致的

但是,$(xxx)[0]就把JQuery对象转化成了DOM对象,一般对象的方法不适用于DOM对象

所以,如果是通过操作DOM拿到的DOM对象,要先把他转化成JQuery对象,再使用对象的方法

  • 扩展:DOM对象转化的方法
    (1)、使用JQuery的$包裹对象;
this.fileObject = $(this.fileObject);

let isEmpty = JSON.stringify(this.fileObject) === '{}';
console.log(isEmpty);    //false
console.log(this.judgeEmptyObjectByObjectKeys(this.fileObject));     //false
console.log(this.judgeEmptyObjectByForIn(this.fileObject));      //false

(2)、使用JSON.stringify()时传入白名单

let file = $('.input-file');
 this.fileObject = file[0].files[0];

let isEmpty = JSON.stringify(this.fileObject,['lastModifiedDate','name','size','type','webkitRelativePath']) === '{}';
console.log(isEmpty);      //false

JSON.stringify(Object,[名单列表])

  • 遗留问题:
    此时的对象是DOM对象,其他的方法判断都是空的,但是JQuery的$.isEmptyObject()却可以正确判断,并且按理说DOM对象是不可以使用JQuery的方法的,但是现在几乎都不城里,不知原因为何?
关于Array-Like(类数组)
  • 场景
    DOM元素通过ClassName或者TagName返回一个“数组”,希望对它进行操作。

  • 实践
    基本的html元素如下:

 <div>
      <div class="element">name</div>
      <div class="element">name</div>
      <div class="element">name</div>
      <div class="element">name</div>
      <div class="element">name</div>
 </div>

通过操作dom拿到相应的数组对象:

let domArray = document.getElementsByClassName('element');
console.log(domArray);
DOM数组对象

判断类型:

console.log(typeof domArray );    //object
console.log(domArray instanceof Array);    //false

此时,这个DOM数组的类型是对象,但又不是数组,只能称之为类数组对象
在JS中,类数组对象是一个很特殊对象,它具有以下的特点:
- 拥有length属性,其它属性(索引)为非负整数
-不具有数组所具有的方法

验证:

console.log(domArray.slice(0,1));
验证结果
  • 扩展:类数组对象转化为数组对象的方法
    为了方便操作类数组对象,使其能够使用数组对象的方法,我们需要将类数组对象转化为数组对象。
    (1)、Array.prototype.slice.call(arguments);
let domArray = document.getElementsByClassName('element');
let nodes = Array.prototype.slice.call(domArray);
console.log(nodes instanceof Array);
console.log(nodes.slice(0,1));

转化结果

(2)、Array.prototype.concat.apply([],arguments);

let domArray = document.getElementsByClassName('element');
let nodes = Array.prototype.concat.apply([],domArray);
console.log(nodes instanceof Array);
console.log(nodes.slice(0,1));

转化结果

(3)、Array.from(arguments);

let domArray = document.getElementsByClassName('element');
let nodes = Array.from(domArray);
console.log(nodes instanceof Array);
console.log(nodes.slice(0,1));
转化结果

(4)、 Object.values(obj)

let domArray = document.getElementsByClassName('element');
let nodes = Object.values(domArray);
console.log(nodes instanceof Array);
console.log(nodes.slice(0,1));

转化结果

(5)、 [...obj]

let domArray = document.getElementsByClassName('element');
let nodes = [...domArray];
console.log(nodes instanceof Array);
console.log(nodes.slice(0,1));
转化结果

结语

这些JS中的细节,看见也没有在意过,但是在具体的问题面前,理解并解决问题也是很重要的。DOM对象是在需求中明确遇到了,类数组对象以前是没有见过的,有一天在社区看见一个人说出去面试遇到了这样的提问,问如何对类数组对象做迭代操作,但是实践中发现,类数组对象也是有length属性,可以通过for…in迭代的,当然也可以转化后再迭代。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容