1. 对象的简单介绍与一些注意事项正则表达式
JavaScript中具备几个简单数据类型:数字、字符串、布尔值、null值以及undefined值。除此以外其他全部值(包括数组、函数,甚至正则表达式)都是对象。数字、字符串以及布尔值表面是对象(由于他们具备方法),但它们是不可变的,只是JavaScript在引用某个数字、字符串或者布尔值时,经过调用new Number()、new String()和new Boolean()构造器将其转换为了数字、字符串或布尔对象,它自有的方法也是从原型中继承而获得。基本数据类型不能够被改变,所以在没有指针再指向它时,它在内存中占用的资源自动被释放,而对象却永远以引用的方式传递,改变对象中的值,也就改变了它在内存中的值。数组
注:理论上说,null值就是null值,不该该被检测为对象,但实际上,因为JavaScript的设计失误,typeof null === "object"是一个事实。闭包
所以在检验null值时,尽可能要使用其余方法如:!null === true。例如,要检测一个刚获取的DOM对象是否正常获取到了,咱们应该使用以下的代码:函数
1 var element = document.getElementById("elementID"); 2 if(element){} 3 // 或者if(!element){}
而不要使用:测试
1 var element = document.getElementById("elementID"); 2 if(typeof element !== "object") {} 3 // 或者if(typeof element === "object") {}
上面说到,由于typeof null === "object",这样下面这段代码中,即便element获取不正常(即值为null)时,if语句也会按照获取正常的结果办事。spa
2. 对象的属性prototype
对象存在的意义就是它能够有许多的属性和方法帮助咱们表达逻辑。对象的属性能够为任意的值,能够是数字、字符串、布尔值、null值,也能够是对象或者是函数(固然函数本质上也是对象)。输出一个属性,若是它已经被定义,可是一个null值,就会对应输出null,若是它甚至还未被定义,就会对应输出undefined。设计
咱们先用字面量定义一个对象,方便后面的测试:指针
1 var game = { 2 name: "Mini Warior", 3 id: 201907271234, 4 qualification: { 5 type: "test" 6 } 7 }
咱们对对象属性的操做通常来讲就是CURD,最经常使用的就是修改更新和检索取值。code
修改更新一个对象的属性,咱们能够直接使用赋值语句。而通常检索并获取对象的属性,有两种方法:第一种,由于更紧凑可读性更强而最为经常使用的一种: var gameName = game.name; 咱们称为(这里有个点↘). 表示法;第二种,就像获取数组对应下标的值同样: var gameName = game["name"]; 。检索获取属性值时,咱们也要考虑到属性不存在的状况,这时候咱们能够巧用运算符填充默认值: var gameName = game.name || "Mini Warior"; 。这时候若是game.name获取为null值或undefined值,gameName也会被赋值为你所但愿的初始值,而不会影响接下来代码的运行。若是咱们尝试从undefined的属性中取值,例如 var gameQualiPlayer = game.qualification.player; ,JavaScript将会抛出一个“TypeError”的错误,咱们也能够巧用&&运算符: var gameQualiPlayer = game.qualification && game.qualification.player; 避免错误,但结果仍然是取出一个undefined值。
处理一些不须要的属性(例如原型链上的属性)时,咱们除了使用typeof关键字之外,还有一种办法是使用Object.prototype.hasOwnProperty()方法。这个方法会返回布尔值,值为填入的参数是否在当前的对象中。比较经常使用的用法是在使用for in语句遍历对象时,for in语句默认会遍历到原型链上的属性。假如在开发过程当中原型链上的属性被其余人修改,而你不清楚,就会发生莫名的错误。所以在使用for in语句时使用这个方法会更为保险:
1 var player = { 2 name: 'Lyn', 3 age: 19, 4 gender: 'male' 5 }; 6 7 var playerPropertyName = []; 8 var playerProperty = []; 9 10 for(var key in player) { 11 playerPropertyName.push(i); 12 playerProperty.push(player[i]); 13 }
上面这段代码把player中的属性的键存入playerPropertyName数组,把player属性的值存入playerProperty数组中。下面在player原型链上加入新的属性,并使用Object.prototype.hasOwnProperty()过滤:
1 var player = { 2 name: 'Lyn', 3 age: 19, 4 gender: 'male' 5 }; 6 player.prototype.playGame = 'Mini Warior'; 7 8 var playerPropertyName = []; 9 var playerProperty = []; 10 11 for (var key in player){ 12 if(player.hasOwnProperty(key){ 13 playerPropertyName.push(i); 14 playerProperty.push(player[i])' 15 } 16 }
这样,在遍历过程当中,就不会把playGame的键和值存到对应数组里面。
对象的属性有的可枚举,有的不可枚举。像咱们上面这样使用for in语句遍历一个对象时,全部可枚举的属性或方法都会受到影响,所以咱们提到可使用typeof关键字或hasOwnProperty方法进行过滤。但咱们知道,JavaScript中Array也是对象,咱们创建数组,输出它,会发现数组的下标是键,值是值,还有一个不可枚举的length属性(固然还有原型)。在这种状况下,咱们使用for in语句就不会影响到length属性。for in语句不只容易遍历到方法和原型属性,还没法控制属性名的顺序,所以咱们遍历的最佳实践应该是使用普通的for语句而不是for in语句(固然,当讲到闭包时,咱们也会发现for语句也并非完美的,但至少它在大多数状况下都比for in遍历要好)。
至于对象属性的删除,咱们会使用到delete运算符,须要注意的一点就是它将不会触及到原型链里的内容,但删除此对象的属性后,可能会让原型链的属性浮现:假设咱们有一个player对象,它有一个属性nickname: "Lyn",它的原型上也有一个属性nickname: "Ben",通过 delete player.nickname; 后,输出player.nickname的值为Ben。
对象帮助咱们编写可扩展、可重用、高质量的JavaScript库。但固然,对象还有几个重要的概念是原型链和对象的建立,它值得咱们放到一篇新的博客中讲述。