JavaScript初阶(九)---------- 对象的枚举、实参列表arguments

 对象的枚举

  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()。

 

posted @ 2017-12-04 11:14  暮雨橙风  阅读(209)  评论(0编辑  收藏  举报