爬虫不得不学之 JavaScript 函数对象篇

九尾龟
• 阅读 1185

今天好像是情人节?所以最适合面向对象,JavaScript 也有对象,我们也可以随时面向对象,方便得很,那怎样才有对象呢?下面告诉你!

1. 数组

数组,字面意思就是一堆数的组合,但是它是有顺序的,学了数组就不仅可以存储一个数据,还可以存储一堆数据,这就是我们为什么学了简单数据类型之后还要学数组的原因。

1.1 声明数组

爬虫不得不学之 JavaScript 函数对象篇

可以看到,数组里面的定义和 python 里的差不多,也可以存储不同数据类型。获取数组元素也是一样通过下标获取,下标从 0 开始,而且 JavaScript 的数组可以随意根据下标进行赋值,不管你的数组长度,因为 JavaScript 的数组长度是动态的。

爬虫不得不学之 JavaScript 函数对象篇

1.2 遍历数组

遍历数组,根据数组长度可以轻易知道循环次数,所以可以使用 for 循环,获取数组的长度可以通过 length 属性进行获取。

爬虫不得不学之 JavaScript 函数对象篇

这里有个提高效率的地方,就是在获取数组的长度时放在了 for 语句的初始化表达式里,而不是放在判断表达式里,当你这个值需要运算才能获得的时候,这样做就可以不用在每次判断时都需要通过运算获得,减少运算,也就提高效率了,当然,数组的长度在这里只是一个属性,不需要运算,放不放在初始化表达式都差不多。

1.3 清空数组

JavaScript 这里清空数组简单粗暴,直接将长度赋值为 0 即可。

爬虫不得不学之 JavaScript 函数对象篇

1.4 数组小练习

  • 找出数组中最大的值

这个直接通过遍历数组,然后将每个值进行比较即可,很容易。

爬虫不得不学之 JavaScript 函数对象篇

  • 翻转数组

这个就是将数组中的元素前后互相替换,也不多说了。

爬虫不得不学之 JavaScript 函数对象篇

2. 函数

当我们需要在对多个数组进行上面的其中练习之一,比如进行寻找最大值,我们总不能每个数组都各自写一段寻找最大值的代码,否则这样子的话代码的复用性太低了。

函数的出现就是解决这个问题的,函数就是把一段相对独立的具有特定功能的代码抽取出来进行封装,形成一个独立的个体。当需要多次使用的时候,我们只需要使用函数名调用即可

2.1 函数的定义

函数定义这里有两种方法,如下:

  • 使用函数声明,语法为

爬虫不得不学之 JavaScript 函数对象篇

爬虫不得不学之 JavaScript 函数对象篇

  • 使用函数表达式,语法为:

爬虫不得不学之 JavaScript 函数对象篇

爬虫不得不学之 JavaScript 函数对象篇

上面只是函数的定义而已,并不会去执行,只有你调用函数的时候才会去执行。

2.2 函数调用

调用函数的语法也比较简单,就是函数加上一个括号就行了。

爬虫不得不学之 JavaScript 函数对象篇

爬虫不得不学之 JavaScript 函数对象篇

所以当需要多次使用这段功能的时候,就多次调用即可,不需要每次都写一段相同的代码。

2.3 函数参数

不需要多次写同一段代码解决了,但是当有不同的数据内容参与运算时,好像我还需要重复写呀!就比如前面说的求数组最大值。这个时候就需要我们的函数参数了,函数参数就是解决这个不确定的数据内容的。当我们需要对不确定数据内容进行操作时,只需要在调用函数的时候把数据内容当作参数传进去即可。

函数的参数定义与调用语法:

爬虫不得不学之 JavaScript 函数对象篇

  • 形参:在声明函数时,有些值是固定的,而有些值不是固定的,对于这些不固定的值,我们可以给它们设置参数,但是这个参数不是具体的值,只是一个形式而已,所以叫做形参
  • 实参:在函数声明设置的形参,我们调用函数就需要传入对应的参数,而这个参数就是实参。

了解了这个之后,是不是很容易就可以写出一个求数组最大值的函数了?

爬虫不得不学之 JavaScript 函数对象篇

咦?上面的我都看明白了,但是 return 那个语句又是什么?return 后面跟的内容就是函数的返回值,当函数运行到这里的时候就会结束函数并且把该值返回给调用处,就相对于一段代码执行之后的反馈所以 return 语句也会常常用于终止函数的运行,还有也可以不写 return 语句,但是会默认返回 undefined

2.4 函数内部的 arguments 对象

JavaScript 中,函数的内部都有一个 arguments 对象,用来记录在调用函数时所传进来的参数,可以说是一个伪数组。

爬虫不得不学之 JavaScript 函数对象篇

爬虫不得不学之 JavaScript 函数对象篇

这个对象可以用于当我们需要传进来的参数个数不确定时就可以使用这个,就比如求一堆数的和。

爬虫不得不学之 JavaScript 函数对象篇

2.5 匿名函数

匿名函数就是没有名字的函数,当我们只需要只需要调用一次的话就可以使用匿名函数,或者需要回调函数的时候就会使用匿名函数,至于什么是回调函数,以后遇到了就说,匿名函数声明如下:

爬虫不得不学之 JavaScript 函数对象篇

这是将匿名函数赋值给一变量,然后可以通过该变量进行调用,也可以传参的,除了这样子调用匿名函数,匿名函数还可以进行自调用。

爬虫不得不学之 JavaScript 函数对象篇

这里需要注意的是在自调用的时候别忘了定义函数的部分需要加括号括起来。这自调用的匿名函数就常用于防止全局被污染,就是当你写的代码量大了,难免会有些全局变量会有重名的可能,这时候使用匿名函数自调用就可以新开辟了一个作用域,不同作用域的变量就算同名也不怕了,至于具体的后面我也会应用到,到时再详讲。

2.6 函数其他

  • 函数也是一种数据类型,可以说是一个对象吧,至于具体的后面再详讲,现在了解就好。

爬虫不得不学之 JavaScript 函数对象篇

  • 函数不仅可以作为参数进行传递,还可以作为返回值,毕竟函数也是一种数据类型。作为参数传递主要就是我们所说的回调函数,遇到就会说,作为返回值的应用,闭包就是一个应用,也不多说,以后会讲。

2.7. 作用域

作用域就是变量可以起作用的范围,在 JavaScript 中定义的变量符合词法作用域,就是说变量的作用域是在定义时决定的,不是在执行时决定的,即变量作用域只需要通过源码分析就知道了。

1. JavaScript 中 词法作用域的规则为:

  • 函数内部的变量允许访问函数外部的。
  • 整个代码结构只能函数限定作用域,这就是为什么上文说使用自调用函数来开辟新的作用域的原因了。
  • 作用域规则首先使用提升规则分析,下文说的预解析就是这个
  • 如果当前作用域有该变量了,就不会考虑外面的了。

2. 下面再看看 JavaScript 中三种作用域

  • 全局作用域:JavaScript 中认为在函数外部定义的变量就是全局变量,而这个全局变量所在的作用域就是全局作用域。
  • 局部作用域:在函数内部就是局部作用域,在这里定义的内部变量也就是局部变量。
  • 块级作用域:这个是 ES6 才有的,简单说下,就是只使用一对大括号{} 括起来的就是块级作用域。

3. 作用域链

只有函数才可以限定作用域,那么在要有代码,这里就至少存在一个全局作用域,而写代码难免又会有函数,这里的函数就会构成另一个作用域,如果函数中还有函数,则他还会构成一个新的作用域,等等。将上面的这些作用域列出来,就会形成一个结构,这个结构就是作用域链。如下面代码:

爬虫不得不学之 JavaScript 函数对象篇

按照全局作用域就是 0 级链,函数就是 1 级链,函数的函数就是 2级链,就会有下图:

爬虫不得不学之 JavaScript 函数对象篇

2.8 预解析

JavaScript 的解释器在执行代码的时候有两个过程,就是预解析和再从上往下执行代码过程。预解析就是先把代码中的变量提升,然后函数提升,接着再执行代码。

  • 变量提升:变量的声明会被提升到作用域的最上面,注不会将赋值提升。
  • 函数提升:把当前作用域的函数声明提升到当前作用域的最上面。

如果你懂了再看看下面几段代码会不会报错?

1.

爬虫不得不学之 JavaScript 函数对象篇

解答:不会报错,因为经过预解析后代码成这样

爬虫不得不学之 JavaScript 函数对象篇

2.

爬虫不得不学之 JavaScript 函数对象篇

解答:也不会报错,不过 a 打印的值为 undefined

爬虫不得不学之 JavaScript 函数对象篇

3.

爬虫不得不学之 JavaScript 函数对象篇

解答:会报错,原因可以结合上下两张图看即可。

爬虫不得不学之 JavaScript 函数对象篇

3. 对象 object

对象是一个具体的事物,比如你和我都是对象,但是汽车和手机不是事物,可以说它们是一个类别。

JavaScript 中的对象可以说是一个无序的属性的集合,属性可以包括基本值、对象或函数,也可以把 JavaScript 中的对象想像为一组键值对。

把现实中的事物抽象为代码中的对象,其的特征可以作为对象的属性,其的行为可以作为方法。

3.1 创建对象

JavaScript 中创建对象的方法有四种,并不像其他语言中只能通过 new 来创建。

  • 直接声明一个键值对的集合

爬虫不得不学之 JavaScript 函数对象篇

这个 obj 变量就是一个对象了里面有两个属性和一个方法。使用这种方法也只适合创建一个类,因为当需要创建大量同类型的对象时,使用这个方法就需要写大量的方法。

  • 使用 new Object() 创建

爬虫不得不学之 JavaScript 函数对象篇

这个是先创建一个空对象,然后动态增加对象的属性和方法,也是只适合创建只有一个对象的类型,还不如第一种,也不推荐。

  • 使用工厂模式创建

爬虫不得不学之 JavaScript 函数对象篇

这种方法就是使用一个模板函数,就相当于一个工厂,还有记得返回创建的对象。当需要创建对象的时候只需要调用一下函数传参就可以了,就比上面两种代码的复用性提高了。

但是这有一个问题,我们在判断对象类型的时候,结果都是 Object

判断对象类型使用 instanceof,而使用 typeof 判断对象,无论什么对象的结果都是 Object

爬虫不得不学之 JavaScript 函数对象篇

  • 自定义构造函数来创建

爬虫不得不学之 JavaScript 函数对象篇

这个自定义构造函数名字需要首字母大写,当然这只是个规范而已

里面使用了 this 关键字,这个 this 的指向就是使用构造函数创建的对象,也不需要返回 对象了。

爬虫不得不学之 JavaScript 函数对象篇

注意:创建对象也需要使用 new 关键字,如上图,通过这种方法就既可以创建大量同类型的对象,也可以判断所属类型,非常方便。

这个 new 创建对象的过程为:

  1. 在内存中先创建一个空的对象
  2. 让构造函数的 this 指向刚刚创建的对象
  3. 执行构造函数内部的属性和方法定义
  4. 返回当前对象

3.2 对象属性和方法的相关操作

  • 访问属性语法为对象.属性,还可以 对象['属性名'] 这样, 当然也可以通过这两个来修改对象属性的值

爬虫不得不学之 JavaScript 函数对象篇

爬虫不得不学之 JavaScript 函数对象篇

当然,当对一个不存在的属性访问的时候就会返回 undefined,若是修改一个不存在的属性就是向该对象动态增加一个新的属性。

这两种方法推荐第二种,因为有时我们得到的属性是一个变量名,并不知道具体的名字,这时候就只能使用第二种方法

  • 访问方法直接使用 对象.函数名() 即可

爬虫不得不学之 JavaScript 函数对象篇

  • 遍历对象成员

可以使用 for...in... 语句

爬虫不得不学之 JavaScript 函数对象篇

  • 删除对象成员

使用 delete 关键字

爬虫不得不学之 JavaScript 函数对象篇

3.3 简单数据类型和复杂数据类型的区别

基本类型又叫做值类型,复杂类型又叫做引用类型

值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。

引用类型:复杂数据类型,在存储时,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。

终于写完了,下一篇常用内置对象走起。

点赞
收藏
评论区
推荐文章
海军 海军
4年前
关于JavaScript 对象的理解
关于JavaScript对象的理解对象理解对象ECMA262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。我们可以把ECMAScript的对象想象成散列表:无非就是一组名值对,其中的值可以是
Wesley13 Wesley13
3年前
java基础
JAVA集合在处理数据的过程中经常会需要一个容器来存储某一类型的数据,Java中的数组就是这样一种容器。但Java中的数组有其局限性,定义后的数组长度不可变,超出数组长度后就不能再存放数据了。而很多时候我们并不知道数据到底有多少,所以就需要有不定长的容器来存放数据,这就是集合,Java中的集合都采用了泛型实现,可以存入任何类型的对象数据
Stella981 Stella981
3年前
JavaScript的 基本数据类型
第一:Javascript对象是第二:Javascript中第三:Javascript的对象是数据;第四:JavaScript中的对象可以简单理解成"名称:值"对(name:value)。名称(name):"名称"部分是一个JavaScript字符串参考https://www
可莉 可莉
3年前
10 个很实用的 JavaScript 技巧
编程语言通常暗藏着各种技巧,熟练使用这些技巧可以提高开发效率。JavaScript就是一门技巧性很强的语言,掌握常见的语法技巧不但可以加深对语言特性的理解,还可以简化代码,提高编码效率。本文分享10个常用的技巧,希望能成为你的开发工具箱的一部分。1arguments对象转成数组arguments对象是函数内可访问的类数组对象,包含了传给函
Stella981 Stella981
3年前
JavaScript学习总结(八)——JavaScript数组
  JavaScript中的Array对象就是数组,首先是一个动态数组,无需预先制定大小,而且是一个像Java中数组、ArrayList、Hashtable等的超强综合体。一、数组的声明  常规方式声明:    1、vararrNamenewArray();//创建一个数组2、vararr
Stella981 Stella981
3年前
JavaScript基础2
普通的JavaScript对象是命名值的无序集合,JavaScript同样定义了一种特殊的对象数组array,表示带编号的值的有序集合,JavaScript为数组定义了专用的语法,使得数组具有区别于普通对象而独有的行为特性JavaScript还定义了另一种特殊对象函数,函数是具有与它相关联的可执行代码的对象,通过调用函数来运行可执行代码并返回运算结
Wesley13 Wesley13
3年前
JS面向对象编程
JavaScript面向对象编程面向对象介绍什么是对象Everythingisobject(万物皆对象)对象到底是什么,我们可以从两次层次来理解。(1)对象是单个事物的抽象。一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个与远程服务器的连接也可
Stella981 Stella981
3年前
Javascript 基础知识学习(四)
这里接着前面一篇继续!Javascript中的所有所有事物都是对象:字符串、数值、数组、函数·····每个对象都有自己的属性和方法,JS能够自定义对象:在第七点是相关面向对象的知识点。<script//直接创建对象varpeople{n
Wesley13 Wesley13
3年前
.Net转Java自学之路—基础巩固篇十三(集合)
集合:集合是用于存储对象的一个工具。  集合与数组的特点    相同点:都是一个容器    不同点:      集合:可以存储对象,只能存储对象,集合长度可变。      数组:可以存储对象,也可以存储基本数据类型,数组长度固定。  容器对象有很多种,通过内部的数据结构来区分,数据结构就是一种数据存储方式。  在不断
Stella981 Stella981
3年前
Javascript 面向对象编程
Javascript面向对象编程(一):封装Javascript是一种基于对象(objectbased)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。那么,如果我们要把"属性
Wesley13 Wesley13
3年前
Java基础学习总结(21)——数组
一.数组的基本概念数组可以看成是多个相同类型数据组合,对这些数据的统一管理。数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组的元素可以是任何数据类型,包括基本类型和引用类型。C和C中的数组都可以分配在栈上面,而JAVA中的数组是只能分配在堆