blog-md
blog-md copied to clipboard
JS 引用类型
引用类型
- 在
ECMAScript
中,引用类型是一种数据结构,用于将数据和功能组织在一起。它也常被称作类。有时候也被成为对象定义,因为他们描述的是一类对象所具有的属性和方法。 - 如前所述,对象是某个特定引用类型的实例。
object 类型
- 一般来说,访问对象属性有点表示法和方括号两种方法。
alert(person['name']) //'James'
alert(person.name) //'James'
这两种方式访问对象属性没有任何区别,但方括号可以通过变量访问属性;如果属性明中国年包含空格等可能导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号正确表达。
Array类型
- 数组的 length 属性并不是只读的。
var color = ['red','blue','green']
color.length = 4
alert(color[3]) //undefined
- 利用 length 属性可以方便的添加末尾项。
color[color.length] = 'black'
- 当设置超过数组长度的数组项时候,数组长度会被重新计算,空的数组项变成了
undefined
.
color[99] = 'brown'
alert(color.length) //100
检测数组
Array.isArray()
-
instanceof
操作符的问题在于,它假定只有一个全局执行环境。如果网页中包含多个框架,实际就存在两个以上不同的全局执行环境,从而存在两个以上的不同版本的Array
构造函数。
栈方法和队列方法
-
push()
方法可以接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组长度。 -
pop()
方法则从数组末尾移走最后一项,减少数组 length,同时返回移除的项。 -
shift()
方法移除数组中的第一项并返回移除的数组项。 -
unshift()
方法则从数组的前端添加任意多项,返回数组长度。 - 由此可见:
push() unshift()
可以接受多项参数,返回的是数组长度 length;pop() shift()
不接受参数,但是返回了一个添加项或者返回项。 -
shift() push()
方法可以模拟队列的方式使用数组,后进前出。 -
unshift() pop()
可以从相反方向模拟队列方法,前进后出。
重排序方法
-
reverse()
反转数组。 -
sort()
默认情况下按升序排列,同时会调用数组项的toString()
方法,即使数组中都是数字,比较的也是字符串,所以常常出现10在5前这种情况。因此默认方法通常不用。
以上两种返回的都是排序后的数组。
function compare(v1, v2) {
return v2-v1
}
[9,3,1,4].sort(compare) //返回的数组即可按升序排列
操作方法
-
concat()
方法没有参数时只会返回复制的数组,有了参数后会返回添加参数后的数组。 -
slice()
方法接受两个参数,起始位置和结束位置。第二个参数可不传。
var color = ['red','blue','green','black','brown']
var color2 = color.slice(1,4)
alert(color2) //['blue','green','black']注意这个地方切到了4前
-
splice()
方法主要用来向数组中部插入项,一般是三种方式: - 删除 :
splice(0,2)
要删除的位置和项数。 - 插入 :
splice(2,0,'red','brown')
在位置2,插入两项。 - 替换 :
splice(2,1,'red','brown')
在位置2删除一项,并插入两项。
位置方法
-
indexOf()和 lastIndexOf()
接受两个参数:要查找的项和起始位置(可选)。 - 只不过一个是从正向开始查找,另一个是从数组末尾开始,但是他们返回的都是找到的项的位置。
迭代方法
-
every()和 some()
返回的是布尔值,表示是否满足某个条件。
var everyResult = color.every(function(item,index,array) {
return (item > 2)
}
alert(everyResult) //false
-
filter()
返回的是符合条件判断的数组。
var filterResult = color.filter(function(item,index,array) {
return (item > 2)
}
alert(filterResult) //[3,5,4,6]
-
map()
方法返回一个对数组的对应项进行操作后的数组。
var mapResult = color.map(function(item,index,array) {
return (item * 2)
}
alert(mapResult) //[2,4,6,8,10]
-
forEach()
直接对数组进行操作,类似 for 循环。
color.forEach(function(item,index,array) {
//进行某些操作
}
归并方法
-
reduce() 和reduceRight()
迭代所有项,返回一个最终值。一个正向迭代,一个从数组末尾向前开始。
var reduceResult = color.reduce(function(pre,next,index,array) {
return pre + next
}
alert(reduceResult) // 所有项想加的结果:15
Function 类型
- 函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。
- 函数声明和函数表达式是有区别的,解析器在代码执行之前,函数声明已经提升,而函数表达式只有执行到它所在的代码行,才会真正解释执行。
函数内部属性
- 函数内部有两个特殊的对象
arguments 和 this
。 -
arguments
主要用来保存函数参数,还有一个callee
属性,是一个指针,只想拥有这个arguments
对象的函数。
function factorial (num) {
if(num < 1) {
return 1
}else {
return num * factorial(num -1)
} //阶乘函数经典形式 问题在于过度紧密耦合了 factorial 函数名
function factorial (num) {
if(num < 1) {
return 1
}else {
return num * arguments.callee(num -1)
} //使用自身函数指针 arguments.callee 替代了函数名,解耦
函数属性和方法
- 每个函数都有两个属性:
length 和 prototype
。其中 length 表示函数接受的参数个数,就引用类型而言,prototype 是保存他们所有实例方法的真正所在。例如toString()和 valueOf()
等方法实际都保存在 prototype 中,只不过是通过各自对象的实例访问罢了。 - 每个实例都包含两个非继承的方法
apply()和 call()
,实际上等于设置函数体内 this对象的值,真正强大的地方是能够扩充函数赖以运行的作用域。call()
是分开接受参数,apply()
是接受数组形式的参数。 - 使用
apply()和 call()
来扩充作用域的最大好处就是,对象不需要与方法有任何耦合关系。此外bind()
也是如此。
单体内置对象
global 对象
-
encodeURI()
方法不会对本身属于 URI 的特殊字符进行编码,:/ ? #
不会转义,会对空格转义。 -
encodeURIComponent()
会对所有非标字符转义。 -
一般来说,
encodeURIComponent()
方法更常用,因为常见的是对查询字符串参数而不是对基础 URI 进行编码。 -
decodeURIComponent()和decodeURI()
是对应的对上述两种方法解码的方法,注意是分别对应,不可交换。 -
escape()
方法已废弃,实践中使用上述方法即可。
Math对象
var max = Math.max(3,54,32,16) //只能对分别的数字参数使用
alert(Max)
var values = [1,2,3,4,5,6,7,8]
var max = Math.max.apply(Math, values)
//这种方式即可对数组进行求最大值的正确姿势
-
random()
方法
套用下面公式,即可从某个整数范围内随机选择一个值。
值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)
//从2到10之间选一个整数
var num = Math.floor(Math.random() * 9 + 2)
function selectNum(lowerVal, upperVal) {
var choiceVal = upperVal - lowerVal + 1
return Math.floor(Math.random() * choiceVal + lowerVal)
}
var num1 = selectNum(2, 10) // 2到10之间选择一个整数