肥宅钓鱼网
当前位置: 首页 钓鱼百科

一个简单的javascript代码(5个提升你JavaScript)

时间:2023-08-18 作者: 小编 阅读量: 3 栏目名: 钓鱼百科

而且对于对象来说,除了函数,都会转换成object。因为每个对象都有一个toString()方法,当要将对象表示为文本值或以预期字符串的方式引用对象时,会自动调用该方法。默认情况下,从Object派生的每个对象都会继承toString()方法。getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。返回值是一个DOMRect对象,是与该元素相关的CSS边框集合。

虽然 2020 的今天,各种前端框架、工具林立,而这些框架跟工具也帮我们提前解决了不少麻烦的问题,但是工具始终是工具,扎实的基本功才是最核心的,现在一起来通过几个实际的代码片段来提高我们原生 JS 的编码水平。

判断数据类型

首先来提问一个:typeof是否能正确判断类型?

答案是:不可以,因为由于历史原因,在判断原始类型时,typeof null会等于Object。而且对于对象来说,除了函数,都会转换成object。例子如下:

typeof 1; // 'number'typeof "1"; // 'string'typeof null; //typeof []; // 'object'typeof {}; // 'object'typeof window.alert; // 'function'

再来提问一个,instanceof是否能正确判断类型?

答案是:还是不可以,虽然instanceof是通过原型链来判断的,但是对于对象来说,Array也会被转换成Object,而且也不能区分基本类型string和boolean。例如:

function Func() {}const func = new Func();console.log(func instanceof Func); // trueconst obj = {};const arr = [];obj instanceof Object; // truearr instanceof Object; // truearr instanceof Array; // trueconst str = "abc";const str2 = new String("abc");str instanceof String; // falsestr2 instanceof String; // true

所以该怎么办呢?

这时候我们可以使用:Object.prototype.toString.call()

所以为什么?

因为每个对象都有一个toString()方法,当要将对象表示为文本值或以预期字符串的方式引用对象时,会自动调用该方法。默认情况下,从Object派生的每个对象都会继承toString()方法。如果此方法未在自定义对象中被覆盖,则toString()返回[Object type],其中type是对象类型。所以就有以下例子:

Object.prototype.toString.call(new Date()); // [object Date]Object.prototype.toString.call("1"); // [object String]Object.prototype.toString.call(1); // [object Numer]Object.prototype.toString.call(undefined); // [object Undefined]Object.prototype.toString.call(null); // [object Null]

所以综合上述知识点,我们可以封装出以下通用类型判断方法:

var type = function(data) {var toString = Object.prototype.toString;var dataType = data instanceof Element? 'element' // 为了统一DOM节点类型输出: toString.call(data).replace(/\[object\s(. )\]/, ''$1') .toLowerCase()return dataType}

使用方法如下:

type("a"); // stringtype(1); // numbertype(window); // windowtype(document.querySelector("h1")); // element

通用的数组/类数组对象封装

如果我们使用 ES5/ES6 的数组 API,很容易就能够对数组进行各类的循环操作,但是如果我们要循环一个类数组对象呢?

例如NodeList。直接循环是会报错的:

document.querySelectorAll("div").map(e => e); // Uncaught TypeError: document.querySelectorAll(...).map is not a function

当然我们可以用扩展运算符:

[...document.querySelectorAll("div")].map(e => e);

那如果我们不用扩展运算符呢?

那么我们就可以利用call的特性,将NodeList里的元素一个一个的插入到数组中,例子如下:

var listMap = function(array, type, fn) {return !fn ? array : Array.prototype[type]["call"](array, fn);};

使用方法如下:

var divs = document.querySelectorAll("div");listMap(divs, "forEach", function(e) {console.log(e);});

获取 dom 元素节点的偏移量

如果有用过jQuery的童鞋,就一定不会忘记$('').offset()这个 api 的强大功能,这个 api 可以轻易获取元素的偏移量,那么如果我们不用jQuery该怎么实现呢?

我们先来看看例子:

var getOffset = function(el) {var scrollTop =el.getBoundingClientRect().topdocument.body.scrollTopdocument.documentElement.scrollTop;var scrollLeft =el.getBoundingClientRect().leftdocument.body.scrollLeftdocument.documentElement.scrollLeft;return {top: scrollTop,left: scrollLeft};};

首先我们先来看getBoundingClientRect()这个方法。

getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。返回值是一个 DOMRect 对象,是与该元素相关的 CSS 边框集合 。

然后就是document.body.scrollTop 跟 document.documentElement.scrollTop这两个是一个功能,只不过在不同的浏览器下会有一个始终为 0,所以做了以上的兼容性处理。所以当我们做拖拽功能的时候,就可以依赖上以上属性。

使用方法如下:

var el = document.querySelector(".moveBox");getOffset(el); // {top: xxx, left: xxx}

我们可以看上面的摇杆效果,这里就是利用了offset()去做位置判断。具体实现代码可以看:https://codepen.io/krischan77/pen/zYxPNPy

Fade 特效

// Fade invar fadeIn = function (el) {el.style.opacity = 0var last =new Date()var tick = function() {el.style.opacity =el.style.opacity(new Date() - last) / 400last =new Date()if ( el.style.opacity < 1) {requestAnimationFrame(tick))}}tick()}// Fade outvar fadeOut = function (el) {el.style.opacity = 1var last =new Date()var tick = function() {el.style.opacity =el.style.opacity - (new Date() - last) / 400last =new Date()if ( el.style.opacity > 0) {requestAnimationFrame(tick)}}tick()}

上述是淡入淡出效果的具体实现,这里是利用requestAnimationFrame对opacity通过递归的方式进行修改。

其实这里需要提一个概念,就是时间分片

这是一个非常重要的概念,例如 ReactFiber 核心实现就是时间分片。它会将一个长任务切分成一个含有若干小任务的任务队列,然后一个接着一个的执行。

requestAnimationFrame就是这样一个 API,它可以根据系统来决定回调函数的执行时机,其实也就是在下一次重绘之前更新动画帧,因为有这样的机制,所以能防止丢帧。

利用队列的概念进行数据操作

队列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为 rear)进行插入操作,在前端(称为 front)进行删除操作。

虽然很多人觉得了解数据结构对前端作用不大,但是如果我们懂一些基础的概念,是否在编码时能够更加扩散我们的思维呢?我们看下面两个例子:

获取节点在该父节点下的坐标。

如果我们要操作原生 DOM,那么是绕不开获取节点在该父节点的下标的这个功能的,那么我们该如何实现呢?

当然就是利用我们的循环啦,对子元素集合进行遍历,直到确定下标为止,代码如下:

var index = function(el) {if (!el) {return -1;}var i = 0;while ((el = el.previousElementSibling)) {i;}return i;};

清空子节点

如果我们要清空某个 DOM 节点的子节点,我们有以下的方法:

var empty = function(el) {while (el.firstChild) {el.removeChild(el.firstChild);}};

上面只是提供一个思路,其实el.innerHTML = ''会更简洁。

利用 reduce 进行数据优化数组去重

没错,又是一个老生常谈的问题,数组去重,但是我们这次去除的不仅仅是单个的数据,而是拥有某个相同键值的对象集合。例如下面的例子,我们有以下的数据:

牛逼的 reduce数据去重

首先我们来看看一个老生常谈的问题,我们假设有这样的一个对象:

const data = [{name: "Kris",age: "24"},{name: "Andy",age: "25"},{name: "Kitty",age: "25"},{name: "Andy",age: "25"},{name: "Kitty",age: "25"},{name: "Andy",age: "25"},{name: "Kitty",age: "25"}];

现在我们要去重里面name重复的对象,这时候我们可以利用reduce,例子如下:

const dataReducer = (prev, cur, idx) => {let obj = {};const { name } = cur;obj[name] = cur;return {...prev,...obj};};const reducedData = data.reduce(dataReducer, {});let newData = Object.values(reducedData);

批量生成对象元素

在鱼头的实际业务中,有一个操作是需要对类似以下的对象进行操作的:

{a1: 'data',a2: 'data',...,an: 'data'}

像我这么懒的鱼,肯定不会一个个手写,所以就有了以下方法

const createList = (item, idx) => {let obj = {};obj[`a${idx}`] = "data";return obj;};const listReducer = (acc, cur) => (!acc ? { ...cur } : { ...cur, ...acc });const obj = Array.from(new Array(20), createList).reduce(listReducer);

文章来源:陈大鱼头

小节

今天的内容就和大家分享到这里,感谢你的阅读。如果你喜欢我的分享,麻烦给个关注、点赞加转发哦,你的支持,就是我分享的动力,后续会持续分享代码片段,欢迎持续关注。

    推荐阅读
  • 螨虫感染自愈(扩散床上螨虫成窝)

    引发黑头、粉刺,以及胸前、背后大片大片痘痘。首先在容器中倒入一勺食盐,食盐有杀菌消毒的作用。接着倒入白醋,白醋有清洁的作用,也能够起到杀菌消毒去异味的作用。最后加入一些小苏打,小苏打有很强的去污能力,搅拌均匀。螨虫喜欢寄居在床垫、地毯、枕垫、坐垫、凉席中,换季时最好及时除螨。需注意,很多人认为开水能烫死螨虫,其实,只有浸泡在开水中半小时以上,除螨效果才明显,很多家庭并不具备这个条件。

  • 玉林市有望成为三线城市(一座潜力很大的)

    玉林市民对这一建设十分的开心,大家纷纷表示,以后出去旅游或者是出差都会方便很多。而外地朋友来玉林做客也会有极大的便利,间接的可以给玉林吸引很多游客。目前来说这两条高速公路已经修建完成,并且正式通车了。而正在规划中的南深高铁目前来说也有意向将玉林规划其中,一旦这个规划落实之后玉林的发展又会实现一个质的腾飞。在广西境内,玉林的经济实力排行大概在第四名左右。

  • 气候危机再次加剧(开辟应对气候变化新路径)

    塑料垃圾不仅对陆地生态系统和海洋生态系统造成严重危害,而且加剧了全球气候变化。截至目前,已有140多个国家明确制定或发布相关禁塑限塑政策。国际竹藤组织提出的“以竹代塑”倡议得到了东道国中国政府的大力支持,并作为全球发展高层对话会的成果之一,被纳入到落实全球发展倡议的具体行动中。此次“以竹代塑”倡议被纳入全球发展高层对话会成果清单,是继往开来的标志性事件,对于全球可持续发展具有重要意义。

  • 释迦果怎么吃有什么功效作用(释迦果怎么吃有什么功效作用和禁忌)

    此食开胃健脾,润肠通便,尤适糖尿病患者食用。柠檬半个个洗净,切开榨汁。将释迦柳橙汁和柠檬汁混合在一起,加入鲜奶90ml、蛋黄1个、蜂蜜10g、冰块100g倒入搅拌杯中,搅拌均匀即成。此汁养颜美容,增强免疫力。

  • 荞麦天天吃对身体好吗(每天吃荞麦好吗)

    了解这方面的朋友很多,首先是因为荞麦蛋白质中含有丰富的赖氨酸成分,同时其他人体所需的微量元素寒凉也非常高,因此对于身体有着非常好的保健作用。很多朋友都知道,粗粮更够有效调节新陈代谢,而荞麦含有的烟酸成分十分丰富,该成分能促进机体的新陈代谢。不仅如此还能够有效增强解毒能力,且具有扩张小血管和降低血液胆固醇的作用。

  • 甘肃第28例造血干细胞捐献成功(桥头小伙为加拿大白血病患者捐献造血干细胞)

    就在2014年11月,他在东莞市桥头镇参与无偿献血时,自愿登记加入中华骨髓库。采集近300分钟后送往大洋彼岸自接到通知,郭立远就积极“奋战”,为了让身体保持最佳状态,他不断加强体育锻炼。东莞市红十字会工作人员表示,郭立远是广东省的首例造血干细胞涉外捐赠,意义重大。虽然东莞开展造血干细胞捐献比较晚,但目前已捐献45例,数量在全省地级市居首位。

  • 2022聊城上半年普通话测试报名费网上缴纳流程

    2022年聊城上半年普通话测试考试费线上缴纳如下:以下内容来源于2022年7月20日聊城教育体育账号一、有工行卡:方法一:(推荐)第一步:。

  • 全国空降什么意思(全国空降意思是什么)

    全国空降就是全国直达的意思降jiàng下落,落下:下降降旨降临降旗空降减低,贬抑:降低降价降职降解(jiě)降心相从姓,接下来我们就来聊聊关于全国空降什么意思?以下内容大家不妨参考一二希望能帮到您!降jiàng下落,落下:下降。简体部首阝部部外笔画6画总笔画8画;繁体部首阜部部外笔画6画总笔画9画。

  • 桔梗怎么吃(桔梗如何吃)

    下面更多详细答案一起来看看吧!桔梗怎么吃材料:桔梗苗500克,葱花15克,精盐3克,味精2克,植物油30克。桔梗苗去杂质,洗净后切段。炒锅上旺火,放油烧至六成热,下葱花煸香,投入桔梗苗煸炒,加精盐,味精炒至入味,出锅装盘即成。

  • 雅思托福对应分数线(雅思分数如何换算托福分数)

    关于托福和雅思的考试区别,想必大家都分得清清楚楚了。比如雅思7分对应的托福分数就是94-101,8分对应的托福分数是110-114。7分是雅思的高分线,但换算成托福分数为94-101分,从印象中来说,这个托福分数段完全是受到鄙视的,可7分的雅思分数,是大多数考生们孜孜以求的。上海三立为学生提供留学咨询规划建议和备考规划。