本章简介

本章内容比较少,有三个分享的知识。你可能都看过了,因为网上也有很多提问和解答,如果没看过或者没搞懂,你可以再看看这篇文章。

1. 数组去重方法的演变    --  走向代码缩短化

2. [] + {} 和 {} + []的返回结果   -- js的代码规范及隐士类型转换

3. ++ [[]][+[]] 的运算   -- 还是++问题

讲解部分

数组去重方法的演变

1. es5以前:

es5以前我们数组去重的方法显得有点笨笨的,我的需要创建一个新数组和一个缓存对象,遍历原来数组,一个个的push到新数组中,如果新数组有当前的元素,就不加了。

var testArray = [1,1,5,76,9,3,2,7,99,3,'a','a']

    var resultArray = null

    function uniqueArray (arr) {
var newArray = []
var cache = {}
var item;
for (var i = 0; i < arr.length; i++) {
item = arr[i]
if (!cache[item] ) { // 如果缓存中没有记录当前元素,意味着新数组中没有这个元素,可以添加
cache[item] = 1
newArray.push(item)
}
}
return newArray;
}
// 毫无疑问,去重了,这里就不展示了
console.log(uniqueArray(testArray))

2. es5时代

试问,es5时代来了,你还在用这样的方法么,答案肯定是不用了,我们该怎么办呢,用filter方法

resultArray = testArray.filter(function (item, index, arr) {
return index === arr.indexOf(item)
})
// 成功
console.log(resultArray)

filter方法是es5中对数组新添加的方法,此方法用来过滤return 为 true的。回调函数接收3个参数,分别是当前元素、当前下标、当前数组(相当于this),代码中我们用arr.indecOf这个es5的方法来取到当前元素的下标再与index比较,达到了过滤重复元素的效果,看以下简单过程

var arr = [1,2,1]
var arr2 = arr.filter(function (item, index, arr) {
return index === arr.indexOf(item)
}} // 以下 = 并未赋值,是数学上的等于意思
// 第一个元素 1: item = 1, index = 0, arr.indexOf(1) = 0,成功加入新数组
// 第二个元素 2: item = 2, index = 1, arr.indexOf(2) = 1, 成功加入新数组
// 第三个元素 1: item = 1, index = 2 , arr.indexOf(1) = 0 ,这里发现indexOf得到的下标并不是2,因为indexOf查找到匹配元素就返回,所以这个元素在之前出现过,因此被屏蔽了。
//最终arr2 = [1,2]

3. es6的问世

es6的出现带来了许多方便的方法,博主也没有仔细看es6的文档,这里介绍两个演变过程。

1). 箭头函数

resultArray = testArray.filter((item, index, arr) => index === arr.indexOf(item))
// 成功
console.log(resultArray)

箭头函数在一定程度上减少了我们的代码量,因此我们可以更简洁的完成es5方法的代码。但这并不是最优的

2). Set结构

Set结构可以接收一个数组,然后把它变成Set表,它会自动屏蔽数组中重复的元素,实现自动过滤

resultArray = [...new Set(testArray)]
// ok
console.log(resultArray)

我们把数组传入Set中,创建一个Set实例,这样就自动完成了过滤,但是这样还不是数组,我们得再把Set结构转化为数组,这就用到了es6中的解构赋值,如上。详情可以看阮一峰老是的es6入门系列。

总结: javascript在不断的变化,不断的成熟,将来会有更多的实用函数提供给我们程序员使用~~~

[] + {} 和 {} + []的运算结果(可以先去试一下)

这个问题是在《你不知道的javascript  中卷》中提出的,书中详细介绍了他们的区别和原因,大家可以去看一下。

1. [] + {}

它返回的是    "[object Object]"   ,是这样一个字符串,很明显他就是一个原始对象的toString()结果,下面我们来介绍一下原因:

大家都知道在 + 运算符有 数学运算功能也有字符串拼接功能,在这里是字符串拼接,因为 此表达式 []  和 {} 需要转化为字符串来进行运算,[]转化为字符串是空字串,{} 转化为字符串就是  "[object Object]",所以理所当然的得到了这个结果。

2. {} + []

它返回了数字 0 ,这就奇怪了,按照上面的逻辑,它不应该还是返回 "[object Object]"么?答案是非,这里牵扯到{}的运用。

javascript解析是从左到右, 在[] + {}中,解析成汉语就是  空数字+ 空对象。

但是在 {} + []中,javascript不会这样解析,因为开始一个{},javascript不认为它是一个空对象,而是把它认为是一个空代码块,就像 if 后面跟着的{}一样,所以javascript解析玩空代码块{}后面就是 + [] , 很明显  ,空数组前面一个+,将数组转化为数字形式,因此得到的结果就是 0

延伸:代码块

在javascript语言{}表示一个代码块,类似于c语言,代码块中可以放任意行的表达式。如:

// if 代码块
if (...) {
// .. 代码块中放代码
} // 普通代码块,和没有一样的结果 {
var a = 1;
}
console.log(a) // // let代码块,创建一个块级作用域
{
left a = 1;
console.log(a) //
}
console.log(a) // 报错

++ [[]][+[]]的运算

这个问题网上也有,在stack overflow 有解答,也有人翻译成了中文,不过我看到解释并不好理解。我是在nodejs群看到的,进群问题就是这个,现在每一个进群的人都会问为什么这个结果是 1 ,看到这问题无数遍了~~~。这个运算不难,但是你可能想当然的理解了,并没有真正的明白,如果你并没有真正的明白,请看这一节。

首先 [+[]]中  + [] 的结果 是 0 ,没有疑问吧,

[[]][0] 这不就是取一个数组的第一个元素么? 然后我们运算出来得到[]

现在变成了  ++ [], 糟糕!报错了,为什么,因为 ++ 不能直接对一个值进行,他需要用变量来做个中转站。之前基础篇已经讲过++了,这里再次深入一下。

var a = 1;

a++ //

1++ //报错,左值无效

以游戏模式通过计算路线图讲解原因:

 a++ , a角色的丹田内原先有1点经验,他又吃了1点经验的经验丹, 这样a角色丹田升级为2点经验。

 1++, 同样的 某个角色丹田有1点经验,这个角色背包游1点经验的经验丹,但是角色没有吃,那么它的丹田依旧1点经验,丹田1 + 背包经验丹1没有结果,所以报错,他们只是两量存在并没有权利升级。

结论: ‘值’ 不能作用于 ++, 因为他们无法变化, 1数字存在于一个内存中, 2数字存在于另一个内存, 1++ 不能将自身内存中的1变为2,数组也一样。

然而变量则是引用了值的量词,变量 ++ ,是 在变量+ 1 的前提下,使变量升级引用比原先值大1的值。

好,++ [] 在这里 也是 []只是个值,并不是个变量,想给自己升级一下,是不可能的,引擎会报错。这个运算流程终结。看正确的流程。

++ [[]][0] 这个体系,是一体的,看下面的问答:

问: [[]][0] 是不是等于 [] 这个值?

答: 是

问: 上面示例a++ 中  a 是不是等于 1 这个值?

答: 是

问: 那么,将a这个变量变成他引用的值也就是1, ++1成立么?

答: 不成立,报错

问: 既然这样,为啥 ++ [[]][0] 你不能当成 一体计算,非要先算 [[]][0]呢, a引用了1, 你算 a++, [[]][0] 只是换了个方式引用[],为啥你非要算++ [],而不是++ [[]][0]

答: 哦,我明白了,这个 [[]][0] 和 a是一样的,都是引用了一个值,然后自增1.所以他的结果就是空数组自增1,空数组转化为Number是0,自增1就等于1了。

问答完了,你应该也懂了吧,废话很多,是因为更详细的介绍出来。

到这里,善于尝试的同学可能会有了一个问题:我在谷歌控制台执行  1 = 1+ 1报错, 但是 [] = [] + 1为啥没报错返回了'1'

那我只能说你很好学,很喜欢动手。

这个问题是为什么呢?那是因为es6的缘故,es6的解构赋值语法,使得[] 在左侧成为了一个合法的值。不信你在其他浏览器试试。

解构赋值也很简单:

[a, b] = [1,2]
a //
b // //也可以用字符串 [c,d] = '12' c //
d//

明白这个问题后,再看  [] = [] + 1, 右边 [] 会变成字符串'', 理所当然得到了 '1', 左边是空的数组,仅仅是没有赋值变量而已,整个表达式返回的就是右边的值‘1’。

结语

语言组织能力差,可能有些地方的语句很糟糕,谅解。。。

javascript提高篇的更多相关文章

  1. javascript提高篇+吐槽

    开篇吐槽 最近一直在投简历找工作,对于博主这样的屌丝应届生来说,一没过硬的技术,二没经验,三没高学历,四没炫酷的项目,五还没漂亮的简历,简直就是3无产品+2b青年.所以快1个月了投的简历没有收到一个面 ...

  2. JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式

    1.单例模式 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  3. JavaScript提高篇之预解释作用域以及this原理及其应用

    1.预解释 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. Spring boot 提高篇

    Spring boot 提高篇 上篇文章介绍了Spring boot初级教程:构建微服务:Spring boot 入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续 ...

  5. JavaScript入门篇

    记录一下在慕课网学习JavaScript的过程. 以下内容均来自慕课网. 传送:https://www.imooc.com/code/401 为什么学习JavaScript 1. 所有主流浏览器都支持 ...

  6. 一步步学习javascript基础篇(0):开篇索引

    索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...

  7. 一步步学习javascript基础篇(3):Object、Function等引用类型

    我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...

  8. Java提高篇——对象克隆(复制)

    假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...

  9. Java提高篇(三三)-----Map总结

    在前面LZ详细介绍了HashMap.HashTable.TreeMap的实现方法,从数据结构.实现原理.源码分析三个方面进行阐述,对这个三个类应该有了比较清晰的了解,下面LZ就Map做一个简单的总结. ...

随机推荐

  1. 手机版的百度map封装,使用gps定位

    代码如下,包自己引 包参考 一个百度MAP导航的基础封装 使用的是浏览器调用gps定位 修改了标注的大小 效果如图: 代码...... <!DOCTYPE html> <html&g ...

  2. SQL循环插入批量数据

    declare @i intdeclare @qid int set @i=1set @qid=100 while @i<50000begininsert into Order(orderid, ...

  3. SQL分页过多时, 如何优化

    问题: 我们经常会使用到分页操作,这里有个问题,在偏移量非常大的时候,它会导致MySQL扫描大量不需要的行然后再抛弃掉.如: , ; 上述这条SQL语句需要查询10020条记录然后只返回最后20条.前 ...

  4. 随机获取指定范围内N个不重复数字

    /// <summary> /// 随机获取指定范围内N个不重复数字 /// </summary> /// <param name="min"> ...

  5. MySQL+Service+Servlet+Jsp实现Table表格分页展示数据

    下面以一个示例讲解如何使用MySQL+Service+Servlet+Jsp实现Table表格分页展示数据: eg:请假管理系统 要求如下: 一.打开首页页面, 访问查询请假记录的 servlet , ...

  6. Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

    最近在开发一个网站时,有个需要是 如果有新预警信息要在网页中播放提示音.页面打开会请求是否有新信息,有则播放提示音.在Chrome的最新浏览器中,播放会报错,控制台显示Uncaught (in pro ...

  7. less的在线安装

    首先打开命令行窗口windonws+r输入cmd回车 1.确认是安装了node和less,在命令行输入“node -v”回车确认node是否安装,有版本信息则安装了,输入“lessc -v”回车确认l ...

  8. PHP && ,and ,||,or 的区别

    PHP中的逻辑“与”运算有两种形式:AND 和 &&,同样“或”运算也有OR和||两种形式. 如果是单独两个表达式参加的运算,两种形式的结果完全相同,例如 $a AND $b和$a & ...

  9. A1037

    给两个序列,一一对应相乘,求最大和. 0不算数,输入时按正负共分为4个数组. #include<cstdio> #include<algorithm> #include< ...

  10. Pytorch之认识Variable

    Tensor是Pytorch的一个完美组件(可以生成高维数组),但是要构建神经网络还是远远不够的,我们需要能够计算图的Tensor,那就是Variable.Variable是对Tensor的一个封装, ...