基本包装对象
- 为了方便基本数据类型的操作(基本数据类型本身是没有属性和方法的),js为number、string、boolean三个基本数据类型提供了基本包装对象,让这三个基本数据类型也能调用一些属性和方法
- 大致操作流程如下:
- 当基本数据类型调用属性或者方法时,它会把基本数据类型当作参数传进构造函数(例如:string的构造函数是String()),接着创建一个临时对象,然后用临时对象调用对应的属性和方法,调用完毕后清空临时对象。所以并不是基本数据类型直接调用了
- 因为临时创建对象只是把基本数据类型的值放进去了,实际上跟基本数据类型本身有可能会不对等,会产生歧义。所以实际上,基本包装对象经常只用于string,其他两个类型用得都很少。
字符串常用属性和方法
- 截取方法
-
字符串.slice(开始位置,结束位置)
截取字符串中的值,注意截取时不包含传入的结束位置 -
字符串.subString(开始位置,结束位置)
截取字符串中的值,注意截取时不包含传入的结束位置 -
字符串.substr(开始位置,截取个数)
截取字符串中的值
-
- 查找位置方法
-
字符串.indexOf(查找值,开始查找位置)
与数字的indexOf方法一模一样,找到返回位置索引,找不到返回-1,所以可以通过do while循环来找到所有值(注意查找位置第一次为0,第二次应该为找到值的后一个开始,所以是索引+1)
-
- 替换方法
-
字符串.replace(查找值,替换值)
这个方法只会替换一次,如果想要将字符串中某一个值全部替换为另一个值有两种方法可以实现。一是用do while配合indexOf,一直循环替换,结束条件是字符串中找不到该值了;二是通过正则表达式来实现。
-
- 通过位置查找字符方法
- 最简单的就是和数组一样,使用
字符串[索引]
的方式来查找,但是这种方法不支持老浏览器。所以还有一种替代方法:字符串.charAt(索引)
,它的作用和前面的是一模一的。如果想统计每个字符出现的次数,可以通过对象计数的方式,再用for in遍历对象即可。
- 最简单的就是和数组一样,使用
- 切割字符串方法
-
字符串.split(分割值)
这个方法可以把字符串根据参数切割后,放进一个新的数组内,并返回这个数组。注意传入的分割值不会放进新数组。
-
- 转换大小写方法
-
字符串.toUppercase();
将英文全部转为大写 -
字符串.toLowercase();
将英文全部转为小写
-
- 总结:字符串的所有方法都不会对原数组进行操作,因为字符串是不可变的,所以它会在操作之后返回到一个新数组中。另外replace和split这两个方法用得比较频繁,要多注意一下。
预解析详解
- 在解析器执行js代码时,它会进行声明提升(即函数声明提升和变量声明提升),所以你会发现先调用函数再声明函数也能正常执行,即把函数和变量声明解析优先级提到最高。
- 但是有一点要注意,变量声明提升不包括赋值,所以你声明一个变量,在预解析时它会预解析变量声明,但是值是undefined,并不包括赋值部分。所以你如果使用函数表达式的方式(
var fun = function(){}
),先调用再声明就会报错,只声明了fun
而它的赋值部分函数体并没有解析。
变量的作用域
- 之前的笔记中已经说了,变量分为全局变量和局部变量(在函数内部声明的变量),从字面意思就知道,全局变量全局使用,局部变量只能在函数体内使用
- 有一种特殊的声明方法,在函数内部声明变量时不写var,而函数的所有上级作用域都没有声明这个变量,那么浏览器会隐式的把它声明为全局变量。
js没有块级作用域
- 在一些其他编程语言中,可以使用{}来限定变量的作用域(即在花括号中声明的变量外部不能使用),但是js没有这个特性,除了函数能限定变量的作用域外,其他任何语法中声明都是全局变量。例如for,if等等
- 另外,一些编程语言会限定for循环中条件值变量的使用,而js不会,条件变量可以直接在外部正常使用。
作用域链
- 首先要明白js的执行顺序,它会优先找到var变量声明和function函数声明,并执行。当全局已经声明完毕后,再开始执行一系列代码操作。
- 在js中作用域是一层嵌套一层的,最高级就是全局作用域,然后多个函数嵌套关系,最外部的函数属于全局,内部的属于上一个函数,依次类推。在函数作用域中执行代码时,也和全局一样。首先找变量和函数的声明,声明完之后,再进行一系列代码的执行
- 在内部作用域中执行变量操作时,它会优先找自己内部声明的变量,如果有直接执行。如果自己内部没找到,会返回上一级作用域中找,还是没找到会再返回上一级作用域找,一直返回到找到后再对该变量的操作,并且只会操作离它最近的作用域内的。如果找到最外层全局作用域还没找到,就会隐式的把该变量声明成全局变量。
- 因为作用域链的嵌套关系比较复杂,所以建议分析代码时,使用教程中提到的画图方式来分析问题,把作用域一层一层的画出来,理解起来会很清晰。