对象的枚举
1. for in循环 (原型链也逃不了)
当我们想把对象的属性一个一个都打印出来的时候,我们就需要用到for in循环
var obj = {
name : "hh",
age : 20
}
for(var prop in obj){
console.log(obj[prop]);
}
其中var prop相当于声明变量,in obj,每次循环从obj里面拿出来一个属性名,obj[prop]就可以得到一个一个属性值。注意:如果这里写成obj.prop 或者 obj["prop"],就会打印
undefined, for in循环只针对处理对象,而且是把var prop写在外面
for in循环也有个问题就是他会把自己原型链上的属性都给打印出来,但我们往往只需要他本身的属性,例如:
Person.prototype.size = "big";
function Person() {
this.name = "hh";
this.age = 20;
}
var son = new Person();
for(var prop in son){
console.log(son[prop]);
}
所以我们就有了下面的方法。
2.hasOwnProperty ------(可以判断是否是自己的属性)
Person.prototype.size = "big";
function Person() {
this.name = "hh";
this.age = 20;
}
var son = new Person();
for(var prop in son){
if(son.hasOwnProperty(prop)){
console.log(son[prop]);
}
}
这样就能只打印出自己的属性。
3.in 操作符 (原型链也逃不了)
用来判断属性是否在某个对象中,注意写成字符串的形式。
Person.prototype.size = "big";
function Person() {
this.name = "hh";
this.age = 20;
}
var son = new Person();
if("name" in son){
console.log('yes')
}
if("size" in son){
console.log('yes')
}
4.instanceof 操作符
判断前面的对象是不是后面的构造函数构造出来的。它是用来判断前面的函数的原型链上是否存在于后面的函数的原型。
function Grand() { }
Person.prototype = new Grand();
function Person() { }
var person = new Person();
person instanceof Person // true
[] instanceof Array // true
Array instanceof Object // true
Object instanceof Array // false
区分数组和对象
利用上面学的部分知识也可以办到
1.instanceof 操作符
Array instanceof Object // true
Object instanceof Array // false
2.利用constructor
var obj = {};
var arr = [];
console.log(arr.constructor) // function Array() { [ native code] }
console.log(obj.constructor) // function Object() { [ native code] }
3.toString方法
因为对象、数组都不能直接用document.write()进行打印,所以系统内部会调用该变量的toString方法。为了方便各种类型的打印,系统在每个原型链上都重写了toString方法。但是我
们需要跳过数组的toString方法,去调用Object上面的toString。这时我们需要使用call来改变this 指向
var obj = { };
var arr = [ ];
var toStr = Object.prototype.toString;
console.log(toStr.call(obj));//[object Object]
console.log(toStr.call(arr));//[object Array]
封装成方法
function isArrayOrObject(target){
var toStr = Object.prototype.toString,
arrStr = '[object Array]';
if(toStr.call(target) === arrStr){
return 'this is Array';
}else{
return 'this is Object';
}
}
arguments(实参列表)
arguments是每个函数都有的一个对象,他有一个属性叫做callee,指向函数本身。
作用:初始化一个很复杂的东西。
var num = (function(n) {
if(n == 1) {
return 1;
}
return n * arguments.callee(n-1);
}
1.callee是一个指针,指向拥有这个arguments对象的函数。
我们来看一个栗子:
function ce(num){
if(num <= 1){ //0的阶乘也是1
return 1;
}
else{
return num*ce(num-1);
}
}
var Ce = ce;
ce = function(num){
return 0;
};
console.log(Ce(10));
运行之后发现结果就是0,原因就是我们在后边修改了ce,ce()永远返回0,而Ce方法里面调用的就是ce的方法,所以结果是0,解决这个问题用arguments.callee属性
function ce(num){
if(num <= 1){ //0的阶乘也是1
return 1;
}
else{
return num*arguments.callee(num-1);
}
}
var Ce = ce;
ce = function(num){
return 0;
};
console.log(Ce(5));
这是输出结果就是120。arguments.callee指向arguments对象的拥有函数引用,当把ce的函数引用赋给Ce后,arguments对象的拥有函数变成了Ce,所以结果是正确的。
2.caller
caller与callee不同,caller属性并不属于arguments对象,它是函数对象的属性,这个属性保存着调用当前函数的函数的引用。
function outer(){
inner();
}
function inner(){
console.log(inner.caller);
}
outer();
让我们来看看运行结果
从结果可知,因为outer()调用了inner(),所以inner.caller就指向outer()。