JS从0开始(十三)对象属性遍历、caller、callee

289 阅读3分钟

方法本身也是属性的一种

一. obj['name']

最早JS引擎:使用 obj['name'] 的写法,
后面出现点的语法:obj.name 其实是系统隐式将它转为obj['name']

二.

遍历:按顺序一个一个获取其信息的过程
枚举:一组有共同数据的集合, JS中枚举就是对象
JS中有遍历就有枚举,它们相辅相成。
JS中数组是特殊的对象

1.用for ... in ... 遍历数组, key是键名

var car = {
  brand : 'Benz',
  color : 'red'
}
/用for ... in ... 遍历数组, key是键名

for(var key in car){
console.log(car.key) /输出undefined,因为JS内置系统将其转化为car['key'],
/即将其认定为字符串的key,在对象中找不到,故输出undefined

console.log( car[key]) /输出 Benz、 red
console.log(key + ':' + car[key])/输出 brand: Benzcolor: red
}

·思路总结

上式中 console.log(car.key)返回undefined,系统隐式的将car.key转为car['key'] , 然后在car里面查找 , 并没有找到字符串'key' , 所以输出undefined
解决方法是用car[key]、key; key是键名即上式的color、brand; car[key]是键值,即上式的Benz、red

2. hasOwnProperty() 排除原型链上的属性

var car = {
  brand : 'Benz';
  color : 'red';
}
Object.prototype.name = 'Object'; /输出的话会出现 name:Object

for(var key in car){
 if(car.hasOwnProperty(key)){
   console.log(car[key]); /这样输出就不会出现原型上的属性
     console.log('name' in car); /返回true
 } 
 console.log('name' in car);/返回true  判断car中是否有'name'这个属性
}

·思路总结

有时候我们只想输出对象中的属性,而不想携带原型链上面的属性。此时就需要hasOwnProperty()
但是在使用in时: console.log('name' in car) ; 返回true ,
这就证明了hasOwnProperty()并没有删除原型链上的属性,利用 hasOwnProperty() 我们只输出了对象中的属性

3. instanceof: 判断这个对象是否 是该构造函数实例化出来的(面试重点)

  function Car(){}
  var car = new Car();

  console.log( car instanceof Car);
  console.log(car instanceof Object);
  console.log([] instanceof Array);
  console.log([] instanceof Object);
  console.log({} instanceof Object);
/以上都返回true 
  

·思路总结

  • a instanceof b 的意思即为 A对象是否属于b
  • 由此可见: 数组既属于数组,又属于对象。数组是特殊的对象

4.三种判断数组的方法

var a = [];
console.log(a.constructor); /1

console.log(a instanceof Array); /2

var str = Object.prototype.toString.call(a);
console.log(str); /3


以后尽可能用第三种方法判断
一般企业中都是用第三种方法,判断后端传过来的数据类型从而做出不同的反应。 一般情况下: 字符串:警告信息; 数组:····· ;
对象:错误信息报告,如微信的:

{
 '10061' : 'error'
}

一般企业中都是用第三种方法:

var a = [];
var str = Object.prototype.toString.call(a);
if(str === '[Object Array]'){
  console.log('是数组');
}else{
  console.log('不是数组');
}

·思路总结

三种方法为:

    1. [ ] .constructor 输出为 : ƒ Array() { [native code] }
      即利用构造器指向函数的形式来确认它是什么类型
  • 2.instanceof
    1. Object.prototype.toString.call(),其方法相当于:
  Object.prototype = {
  toString:function(){
     a.toSring(); /call 改变this指向
  }
}

数组输出[object Array]、字符串输出[object、String]、数字输出[object、Number]等

5. this的指向

1.全局的this指向window
2.在函数内部,普通的函数默认指向window(未被实例化)
3.构造函数实例化后 this指向被实例化出来的对象
4.call、apply更改this指向

6.callee/caller (笔试重点)

  • arguments.callee 执行到这一句的时候,返回正在被执行的函数对象
test(1,2)
  function test(a,b,c){
    console.log(arguments.callee.length); /输出3 ,该函数形参有三个,第三个为undefined
    console.log(arguments.length);/输出2
    
   console.log(arguments.callee); /返回:ƒ test(a,b,c){
                                 / console.log(arguments.callee.length); 
                                 / console.log(arguments.length);
                                 / console.log(arguments.callee);
                                 /  } 
                           /即返回其所处的函数内的所有内容,包括里面的函数
    test3();
   function test3(){
    console.log(arguments.callee);
   } /返回ƒ test3(){
     / console.log(arguments.callee);
      / }
      / 即不返回函数外面的函数
  }
  

  • caller 返回当前被调用函数的函数引用:
 function test1(){
    test2(); 
  }
 function test2(){
   console.log(test2.caller); 
 }
 test1();
 
 返回ƒ test1(){
    test2(); 
  }
   / 哪个函数调用函数test2,就返回哪个函数的所有内容

·思路总结

  1. arguments.callee返回其所处的函数内的所有内容。注意是函数内,函数外部的函数不会返回,函数里面的函数会返回,详见上例。
    2. console.log ( 函数1.caller ): 哪个函数调用函数1,就返回哪个函数的所有内容