零. 扯两句
我决定要把几个我最近遇到的觉得比较有用的js方法记录一下,配上一些个人理解。观众别见笑,可能对你来说非常简单。
他们分别是
-
hasOwnProperty
判断对象是否拥有某个自有属性。 -
propertyIsEnumerable
判断对象的自有属性是否可枚举。 -
apply
与call
的用法。
一. 我们一个个来
1. hasOwnProperty
hasOwnProperty
用来判断一个对象是否有你给出名称的属性。不过这个方法无法检测该对象的原型链中是否具有该属性(也就是说只能用来判断自有属性)。举个例子
> var str = "javascript";
> str.hasOwnProperty("split")
false
> String.prototype.hasOwnProperty("split")
true
原型链上有split
这个属性,但是它并不是一个自有属性,所以结果为false
。而str实际上是可以调用这个方法的。
> str.split('')
[ 'j', 'a', 'v', 'a', 's', 'c', 'r', 'i', 'p', 't' ]
再举个例子
> var str = {x: 1}
undefined
> str.hasOwnProperty("x")
true
> str.hasOwnProperty("toString")
false
toString
是从Object.prototype
这个原型继承过来的属性所以这里返回false
。而x
是自身的属性,所以返回true
。
2. propertyIsEnumerable
这个方法用来判断对象属性是否可枚举。
什么叫做可枚举?
我总结为可以for
出来的就是可以枚举的
。属性是否是可枚举的
我们在ES5之后有对应的方法可以去设置了。这些方法以后以机会再说。
稍微熟悉JS都知道,我们所有的对象都继承自Object.prototype
这个原型对象。我们看下面这个脚本
> var a = {x: 2}
undefined
> a.x
2
> a.toString()
'[object Object]'
> for (var i in a) { console.log(i)}
x
undefined
可否看到?对象a
具有属性x
而a
同时也可以调用toString
方法,但是这里的属性x
是可枚举的,属性toString
是不可枚举的(这个是在原型那边已经设置好的了)。
于是,我们可以方便地这样判断
> a.propertyIsEnumerable('x')
true
> a.propertyIsEnumerable('toString')
false
3. apply 和 call
简单地区分这两个东西他们接收参数的方式不一样。call
接收的参数应该是参数列表
,而apply
接收的参数是参数所组成的数组
。
举个简单的例子如果要调用对象的一个方法,我们可以直接通过对象.方法名
的方式来调用。
比如当我们要拼接两个数组的时候,可以这样做。
> var a = [1,2,3,4,5,6]
undefined
> a.concat([2,3,4,5,6])
[ 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6 ]
然而,我们还可以这样做
直接通过Array原型调用。
call
版本
fun.call(thisArg, arg1, arg2, arg3)
> Array.prototype.concat.call(a, [2,3,4,5,6])
[ 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6 ]
apply
版本
fun.apply(thisArg, [argsArray])
> Array.prototype.concat.apply(a, [[2,3,4,5,6], [2,3,4,5,6]])
[ 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6 ]
稍微深度思考一下
当然,如果大胆一点这样也行
Array.prototype.concat(a, [2,3,4,5,6])
[ 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6 ]
我去,这什么鬼,怎么跟之前的a.concat([2,3,4,5,6])
拼接的结果一样?容小弟来分析一下。
首先我们看看这样一个拼接结果
a.concat([2,3,4], [5,6])
它跟a.concat([2,3,4,5,6])
的结果是一样的,也是[ 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6 ]。
这表示concat
是可以接收多个参数的。这样的话如果我们[].concat(a, [2,3,4,5,6])
的结果岂不是也等于a.concat([2,3,4,5,6])
。不巧的是,这里数组的原型Array.prototype
恰好就等于[]
。
> Array.prototype
[]
换算起来就是[].concat(a, [2,3,4,5,6])
因此最终结果跟a.concat([2,3,4,5,6])
是一样的。
好诡异的机制。
二.最后
这几个方法比较简单,我附带一些个人的理解。希望您不会觉得啰嗦。