第4章 变量、作用域和内存问题
4.1 基本类型和引用类型的值
基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。
基本数据类型:boolean,number,null,undefined,string
引用类型的值是按引用访问的。
对引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。
如果对象不被销毁或者这个属性不被删除,这个属性将一直在。
但是,我们不能给基本类型的值添加属性。尽管这样做不会导致任何错误。
4.1.2 复制变量值
一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。但二个变量的值是完全独立的,二个变量可以参加任何操作而不会相互影响。
一个变量向另一个变量复制引用类型的值时,同要也会将存储在变量对象中的值复制一份到新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象,因此,改变其中一个变量,就会影响另一个变量。
4.1.4 检测类型
typeof是检测基本数据类型最佳工具,但在检测引用类型的值时,这个操作符的用处不大。
ECMAScript提供了instanceof操作符,语法如下
Result = variable instanceof constructor;
如果变量是给定引用类型的实例,那么instanceof操作符就会返回true;
根据规定,所有的引用类型的值都是Object的实例,因此,在检测一个引用类型值和Object构造函数时,instanceof值始终会返回true。当然如果用instanceof操作符检测基本类型的值,则该操作符始终会返回false,因为基本类型不是对象。
4.2 执行环境及作用域
在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出——例如关闭网页或浏览器时才会被销毁)。
4.3 垃圾回收
调用window.CollectGarbage()方法会立即执行垃圾收集。
在Opera7及更高版本中,调用window.opera.collect()也会启动垃圾收集例程。
确保占用最少的内容可以让页面获得更好的性能。优化内在战胜的最佳方式,就是为自毁长城中的代码只保存必要的数据,一量数据不再有用,最好通过装饰其值设置为null来释放其引用。
第5章 引用类型
在ECMAScript中,引用类型是一种数据结构。用于将数据和功能组织在一起。
5.1 Object 类型
我们大多数引用类型值都是Object类型的实例; Object也是ECMAScript中使用最多的一个类型。
创建Object实例的方式有二种,第一种是使用new操作符后跟Objcet构造函数
var person = new Object();
person.name =”lee”;
person.age =”27”
另一种方式是使用对象字面量表示法。是对象定义的一种简写形式。
var person ={ name:”lee”,age:29}
5.2 Array 类型
除Object之外,Array类型恐怕是ECMAScript中最常用的类型了。
ECMScript数组的每一项可以保存任何类型的数据。
创建数组的二种方式,一种使用Array构造函数
var colors = new Araay();
如果预先知道组织要保存的项目数据,可给构造函数传递数量,该业务量自动变成length属性值。
也可传递数组中应该包含的项。
在作用构造函数创建时也可省略new操作符。
第二种方法,使用数组字面量表示法。
Var colors = [];
5.2.1 检测数组
Istanceof Array
Array.isArray(value);
5.2.2 转换方法
toLocaleString() toString() valueOf()
5.2.3 栈方法
栈是一种LIFO(last-in-first-out后进先出)
push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度
pop()方法从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。
5.2.4 队列方法
队列数据访问规则是FIFO(first-in-first-out 先进先出)。
Sthift() 删除数组的第一项,并返回删除的值
Sthift()和push()同时使用,可以像使用队列一样使用数组。
unshift() 在数组的前端添加任意个项,并返回新数组的长度
unshift()和pop()同时使用,可以从相反的方向来模拟队列,即从前端添加项,从末端移除项。
5.2.5 重排序方法
数组中已经存在二个可以直接用的重排序的方法:
reverse():从大到小
sort():从小到大 sort()方法可以接收一个比较函数作为参考,以便我们指定哪个值位于哪个值的前面。
5.2.6 操作方法
concat():基于当前组织中的所有项创建一个新数组。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给concat()方法传递参数的情况下,它只复制当前数组并返回副本。如果传递给concat()方法的是一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数值,这些值就会被简单的添加到结果数组的末尾。
Slice():它能够基于当前缓缓中的一或多个项创建一个新数组。Slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。只有一个参数的情况下,slice()方法返回从该参数指定位置开始到数组末尾的所有项。如果有二个参数,该方法返回起始和结束位置之间的项,但不包括结束位置的项。Slice()方法不会影响原始数组。
如果slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位置,如长度5,调用slice(-2,-1)与调用slice(3,4)得的的结果相同。如果结束位置小于起始位置,则返回空数组。
splice():这个方法算是最强大的数组方法,它有很多种用法,主要用途是向数组的中部插入项,但使用这种方法的方式则有如下3种。
删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。如:splice(0,2)会删除数组中的前两项。
插入:可以向指定位置插入任意数量的项,只需提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。
替换:
可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定3个参数:起始位置,要删除的项数和要的任意数量的项,插入的项数不必与删除的项数相等。
splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)
5.2.7 位置方法
二个方法都接收二个参数,要查找的项和查找起点位置的索引(可选、非必须)
indexOf():从数组的开头开始向后查找
lastIndexOf():从数组的末尾开始向前查找
二个方法都返回要查找的项在数组中的位置,没找到的情况下返回-1.
在比较参数与数组的每一项时,会使用全等操作符。查找的项必需严格相等,就像使用===一样。
5.2.8 迭代方法
ECMAScript为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数(可选的)运行该函数的作用域对象——影响this的值。传入这些方法中的函数接收三个参数:数组项的值、该项数组中的位置和数组对象本身。
语法:arrar.filter(function(item,index,array){ return item ==1});
every()返回boolean值 完全符合条件
some()返回boolean值 部分符合条件
filter()返回符合条件的数组值
map()返回一个数组,而这个数组的每一项都是在原始数组中的对应项上运行传入函数的结果。例,给数组中的每一项*2,然后返回这些积组成的数组。
var numbers = [1,2,3,4,5]
var result = numbers.map(function(item,index,array){retrn item*2});
//[2,4,6,8,10]
forEach()没有返回值。本质上与使用for循环迭代数组一样。
IE9+才支持这些迭代方法的
5.2.9 缩小方法
reduce()从前到后
reduceRight()从后到前
迭代数据的所有项,构建一个最终返回值。
接收4个参数:前一个值,当前值,项的索引和数组对象。
5.3 Date类型
Date类型使用自UTC(国际协调时间)1970年1月1日午夜(零时)开始经过的毫秒数来保存日期。
Date.parse():接收到个表示日期的字符串参数,然后尝试根据字符串返回相应期的毫秒数。
Date.UTC()。
5.3.2 日期格式化方法
toDateString()
toTimerString()
toLocaleDateSting()
toLocaleTimeString()
toUTCString()
5.3.3 日期、时间组件方法
方法 |
说明 |
getTime() |
返回表示日期的毫秒数;与valueOf()返回值相同 |
setTime(毫秒) |
以毫秒数设置日期,会改变整个日期 |
getFullYear() |
取得4们数的年份 |
getUTCFullYear() |
返回UTC日期的4位年份 |
setFullYear(年) |
设置日期的年份。传入的年份值必需是4位数 |
setUTCFullYear(年) |
设置UTC日期的年份。传入的年份必须是4位数 |
getMonth() |
返回日期中的月份,其中0表示1月,11表示12月 |
5.4 RegExp类型
g:表示全局(global),应用于所有字符串,而非在发现第一个匹配项立即停止
i:表示不区分大小写(case-insensitive)。即在确定匹配时忽略模式与字符串的大小写。
m:表示多行(multiline),到达一行文本末尾时还会继续查找下一行是否存在与模式匹配的项。
5.4.1 RegExp实例属性
global:布尔值,表示是否设置了g标志。
ignoreCase:布尔值,表示是否设置了i标志。
lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0算起。
multiline:布尔值,表示是否设置了m标示
source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
5.4.2 RegExp实例方法
exec():该方法是专门为捕获组而设计的。Exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。返回的数组虽然是Array的实例,但包含两个额外的属性:index和input。其中,index表示匹配项的字符串中的位置,而Input表示应用正则表达式的字符串。
test():它接受一个字符串参数。在模式与该参数匹配的情况下返回true,否则,返回false。在只想知道字符串与某个模式是否匹配,但不需要其文本内容的情况下,使用这个方法非常方便。因为text()方法经常被用在if语句中。
5.5 function 类型
5.5.4函数内部属性
Arguments和this
Arguments有一个名叫callee的属性:函数arguments的名称
this:this引用的是函数据以执行的环境对象
caller
5.5.5 函数属性和方法
length:函数参数的长度
prototype:是保存它们所有实例方法的真正所在。在创建自定义引用类型以及实现继承时,prototype极为重要,ECMAScript中,prototype属性是不可枚举的。
每个函数都包含两个非继承而来的方法:
apply():接受二个参数,一个是其中运行函数的作用域,另一个是参数数组。第二个参数可以是Array的实例,也可以是argumenets对象
call():
它们的区别仅在于接受参数的方式不同,第一个参数是this没有变化,变化的是其余参数都直接传递给函数。在使用call方法时,传递给函数的参数必须逐个例举出来。
它们真正强大的地方是能够扩充函数赖以运行的作用域
bind()这个方法会创建 一个函数的实例。其this值会绑定到传给bind()函数的值。
5.6 基本包装类型
3个特殊的引用类型:boolean,number,string
基本类型值不是对象,因而从逻辑上讲它们不应该有方法(它们确实有方法)。
1、创建String类型的一个实例;
2、在实例上调用指定的方法
3、销毁这个实例
var s1 = new Sting(“some text”);
var s2 = s1.substring(2);
s1=null
经过此番处理,基本的字符串值就变得跟对象一样了。而且,上面这三个步骤也分别适用于boolean,和number类型对应的布尔值和数字值。
引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内在中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。
Substring
5.6.2 number类型
Number类型也重写了valueOf(),toLocaleString(),tostriong()
toFixed() 四舍五入
5.6.2 string类型
valueOf(),toLocaleString(),toString()
属性:length
1字符方法:
charAt()
charCodeAt()
2字符串操作方法:
concat()
slice()
substr()
substring()
3字符串位置方法
indexOf()
lastIndexOf()
4trim()方法
创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果
5字符串大小写转换法
toLowerCase()
toUpperCase()
toLocaleLowerCase()
toLocaleUpperCase()
6字符串的模式匹配方法
match():在字符串上调用这个方法,本质上与regexp的exec()方法要同。
此方法只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象。
search(),这个方法的参数与match()方法相同,search()方法返回字符串中第一个匹配项的索引,如果没有则返回-1,
replace(),接受二个参数;第一个可以是正则,也可以是字符串,第二个参数可以是字符串或者一个函数。
split():
7localeCompare()方法
比较字符串,并返回下列值中的一个:
如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1)
如果字符串等于字条串参数,返回0
如果字条串在字母表中应该排在字符串参数之后,则返回一个正数,(大多数情况下是1)
8fromCharCode()方法
这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串。
9HTML方法
anchor(name) //<a name=”name”>string</a>
big() //<big>string<big>
bold() //<b>string</b>
fixed() //<tt>string</tt>
fontcolor(color) //<font color=”color”>string</font>
fontsize(fontsize) //<font size=”size”>string</font>
italics() //<i>string</i>
link(url) //<a href=””>string</a>
small() //<small>string</small>
strike() //<strike>string</strike>
sub() //<sub>string</sub>
sup() //<sup>string</sup>
5.7 单体内置对象
ECMAScript对内置对象的定义是:由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。
例如Object,Array,String
还定义了两个单体内置对象:
Global 和 Math
5.7.1 Global对象
isNaN(),isIfinite(),parseInt(),parseFloat()
全都是Global对象的方法 除此之外,还包含其他一些方法
1.URI编码方法
encodeURI()
encodeURIComponent()
可以对URI(Uniform Resource Identifiers,通用资源标识符)进行编码,以便发送给浏览器。
decodeURI()
decodeURIComponent()
2.eval()对象
3.Global对象的属性
4.window对象
5.7.2 Math对象
保存数学公式和信息提供了一个公共位置,即Math对象。
1.Math对象的属性
Math.E
P134 用时可查阅
2.min()和max()方法
确定最大值和最小值
要找出数组中间的最大值或最小值可以使用apply()方法
var s1=[5,35,65,22]
var max = Math.max.apply(Math,s1)
3.舍入方法
Math.ceil():向上舍入,即它总是将数值向上舍入为最接近的整数
Math.floor():向下舍入,即它总是将数值向下舍入为最接近的整数
Math.round():标准舍入,将数值四舍五入为最接近的整数
4.random()方法
返回介于0和1之间一个随机数,不包括0和1
值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能值)