zzrshuiwuhen 2019-06-30
今天好像是情人节?所以最适合面向对象,JavaScript 也有对象,我们也可以随时面向对象,方便得很,那怎样才有对象呢?下面告诉你!
数组,字面意思就是一堆数的组合,但是它是有顺序的,学了数组就不仅可以存储一个数据,还可以存储一堆数据,这就是我们为什么学了简单数据类型之后还要学数组的原因。
可以看到,数组里面的定义和 python 里的差不多,也可以存储不同数据类型。获取数组元素也是一样通过下标获取,下标从 0 开始,而且 JavaScript 的数组可以随意根据下标进行赋值,不管你的数组长度,因为 JavaScript 的数组长度是动态的。
遍历数组,根据数组长度可以轻易知道循环次数,所以可以使用 for 循环,获取数组的长度可以通过 length 属性进行获取。
这里有个提高效率的地方,就是在获取数组的长度时放在了 for 语句的初始化表达式里,而不是放在判断表达式里,当你这个值需要运算才能获得的时候,这样做就可以不用在每次判断时都需要通过运算获得,减少运算,也就提高效率了,当然,数组的长度在这里只是一个属性,不需要运算,放不放在初始化表达式都差不多。
JavaScript 这里清空数组简单粗暴,直接将长度赋值为 0 即可。
这个直接通过遍历数组,然后将每个值进行比较即可,很容易。
这个就是将数组中的元素前后互相替换,也不多说了。
当我们需要在对多个数组进行上面的其中练习之一,比如进行寻找最大值,我们总不能每个数组都各自写一段寻找最大值的代码,否则这样子的话代码的复用性太低了。
函数的出现就是解决这个问题的,函数就是把一段相对独立的具有特定功能的代码抽取出来进行封装,形成一个独立的个体。当需要多次使用的时候,我们只需要使用函数名调用即可。
函数定义这里有两种方法,如下:
上面只是函数的定义而已,并不会去执行,只有你调用函数的时候才会去执行。
调用函数的语法也比较简单,就是函数加上一个括号就行了。
所以当需要多次使用这段功能的时候,就多次调用即可,不需要每次都写一段相同的代码。
不需要多次写同一段代码解决了,但是当有不同的数据内容参与运算时,好像我还需要重复写呀!就比如前面说的求数组最大值。这个时候就需要我们的函数参数了,函数参数就是解决这个不确定的数据内容的。当我们需要对不确定数据内容进行操作时,只需要在调用函数的时候把数据内容当作参数传进去即可。
函数的参数定义与调用语法:
了解了这个之后,是不是很容易就可以写出一个求数组最大值的函数了?
咦?上面的我都看明白了,但是 return 那个语句又是什么?return 后面跟的内容就是函数的返回值,当函数运行到这里的时候就会结束函数并且把该值返回给调用处,就相对于一段代码执行之后的反馈。所以 return 语句也会常常用于终止函数的运行,还有也可以不写 return 语句,但是会默认返回 undefined
JavaScript 中,函数的内部都有一个 arguments 对象,用来记录在调用函数时所传进来的参数,可以说是一个伪数组。
这个对象可以用于当我们需要传进来的参数个数不确定时就可以使用这个,就比如求一堆数的和。
匿名函数就是没有名字的函数,当我们只需要只需要调用一次的话就可以使用匿名函数,或者需要回调函数的时候就会使用匿名函数,至于什么是回调函数,以后遇到了就说,匿名函数声明如下:
这是将匿名函数赋值给一变量,然后可以通过该变量进行调用,也可以传参的,除了这样子调用匿名函数,匿名函数还可以进行自调用。
这里需要注意的是在自调用的时候别忘了定义函数的部分需要加括号括起来。这自调用的匿名函数就常用于防止全局被污染,就是当你写的代码量大了,难免会有些全局变量会有重名的可能,这时候使用匿名函数自调用就可以新开辟了一个作用域,不同作用域的变量就算同名也不怕了,至于具体的后面我也会应用到,到时再详讲。
作用域就是变量可以起作用的范围,在 JavaScript 中定义的变量符合词法作用域,就是说变量的作用域是在定义时决定的,不是在执行时决定的,即变量作用域只需要通过源码分析就知道了。
1. JavaScript 中 词法作用域的规则为:
2. 下面再看看 JavaScript 中三种作用域
3. 作用域链
只有函数才可以限定作用域,那么在要有代码,这里就至少存在一个全局作用域,而写代码难免又会有函数,这里的函数就会构成另一个作用域,如果函数中还有函数,则他还会构成一个新的作用域,等等。将上面的这些作用域列出来,就会形成一个结构,这个结构就是作用域链。如下面代码:
按照全局作用域就是 0 级链,函数就是 1 级链,函数的函数就是 2级链,就会有下图:
JavaScript 的解释器在执行代码的时候有两个过程,就是预解析和再从上往下执行代码过程。预解析就是先把代码中的变量提升,然后函数提升,接着再执行代码。
如果你懂了再看看下面几段代码会不会报错?
1.
解答:不会报错,因为经过预解析后代码成这样
2.
解答:也不会报错,不过 a 打印的值为 undefined
3.
解答:会报错,原因可以结合上下两张图看即可。
对象是一个具体的事物,比如你和我都是对象,但是汽车和手机不是事物,可以说它们是一个类别。
JavaScript 中的对象可以说是一个无序的属性的集合,属性可以包括基本值、对象或函数,也可以把 JavaScript 中的对象想像为一组键值对。
把现实中的事物抽象为代码中的对象,其的特征可以作为对象的属性,其的行为可以作为方法。
JavaScript 中创建对象的方法有四种,并不像其他语言中只能通过 new 来创建。
这个 obj 变量就是一个对象了里面有两个属性和一个方法。使用这种方法也只适合创建一个类,因为当需要创建大量同类型的对象时,使用这个方法就需要写大量的方法。
这个是先创建一个空对象,然后动态增加对象的属性和方法,也是只适合创建只有一个对象的类型,还不如第一种,也不推荐。
这种方法就是使用一个模板函数,就相当于一个工厂,还有记得返回创建的对象。当需要创建对象的时候只需要调用一下函数传参就可以了,就比上面两种代码的复用性提高了。
但是这有一个问题,我们在判断对象类型的时候,结果都是 Object
判断对象类型使用 instanceof,而使用 typeof 判断对象,无论什么对象的结果都是 Object
这个自定义构造函数名字需要首字母大写,当然这只是个规范而已。
里面使用了 this 关键字,这个 this 的指向就是使用构造函数创建的对象,也不需要返回 对象了。
注意:创建对象也需要使用 new 关键字,如上图,通过这种方法就既可以创建大量同类型的对象,也可以判断所属类型,非常方便。
这个 new 创建对象的过程为:
当然,当对一个不存在的属性访问的时候就会返回 undefined,若是修改一个不存在的属性就是向该对象动态增加一个新的属性。
这两种方法推荐第二种,因为有时我们得到的属性是一个变量名,并不知道具体的名字,这时候就只能使用第二种方法
可以使用 for...in... 语句
使用 delete 关键字
基本类型又叫做值类型,复杂类型又叫做引用类型
值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。
引用类型:复杂数据类型,在存储时,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。
终于写完了,下一篇常用内置对象走起。