JavaScript面向对象_1
-
点表示法
在上面的例子中,使用了点表示法(dot notation)来访问对象的属性和方法。对象的名字表现为一个命名空间(namespace),它必须写在第一位——当你想访问对象内部的属性或方法时,然后是一个点(.),紧接着是你想要访问的项目,标识可以是简单属性的名字(name),或者是数组属性的一个子元素,又或者是对象的方法调用。如下所示:
person.age person.interests[1] person.bio()
1. 子命名空间
可以用一个对象来做另一个对象成员的值。例如将name成员
1 name : ['Bob', 'Smith'],
改成
1 name : { 2 first : 'Bob', 3 last : 'Smith' 4 },
//或者是 ‘first’:first, ‘last’:last 用来传进参数
这样,我们实际上创建了一个子命名空间,听起来有点复杂,但用起来很简单,你只需要链式的再使用一次点表示法,像这样:
1 person.name.first 2 person.name.last
注意:你需要改变你之前的代码,从
name
[0]
name
[1]
改成
name
.first
name
.last
-
括号表示法
person
['age']
person
['name']['first']
难怪对象有时被称之为关联数组(associative array)了——对象做了字符串到值的映射,而数组做的是数字到值的映射
括号表示法一个有用的地方是它不仅可以动态的去设置对象成员的值,还可以动态的去设置成员的名字
E.g.:
比如说,我们想让用户能够在他们的数据里存储自己定义的值类型,通过两个input框来输入成员的名字和值,通过以下代码获取用户输入的值:
var myDataName = nameInput.value; var myDataValue = nameValue.value;
我们可以这样把这个新的成员的名字和值加到person对象里:
person[myDataName] = myDataValue;
为了测试这个功能,尝试在你的代码里添加以下几行,就在person对象的右花括号的下面:
var myDataName = 'height'
var myDataValue = '1.75m'
person[myDataName] = myDataValue
现在,保存并刷新,在输入框里输入以下代码:
person.height
注意:这是使用点表示法无法做到的,点表示法只能接受字面量的成员的名字,不接受变量作为名字。
一.创建对象实例的方法
-
声明一个对象(复用效率不高)
1 var person = { 2 name: ['Bob', 'Smith'], 3 age: 32, 4 gender: 'male', 5 interests: ['music', 'skiing'], 6 bio: function() { 7 alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); 8 }, 9 greeting: function() { 10 alert('Hi! I\'m ' + this.name[0] + '.'); 11 } 12 };
在控制台调用
1 >person.name[0] 2 >person.age 3 >person.interests[1] 4 >person.bio() 5 >person.greeting()
-
利用构建函数创建对象(可传入属性值)
1 function Person(name) { 2 this.name = name; 3 this.greeting = function() { 4 alert('Hi! I\'m ' + this.name + '.'); 5 }; 6 }
注: 一个构建函数通常是大写字母开头,这样便于区分构建函数和普通函数。
那如何调用构建函数创建新的实例呢?
1.将下面的代码加在您之前的代码下面:
1 var person1 = new Person('Bob'); 2 var person2 = new Person('Sarah');
2.保存并刷新浏览器,在 console 里输入如下代码:
>person1.name >person1.greeting() >person2.name >person2.greeting()
稍复杂的构造函数
1 function Person(first, last, age, gender, interests) { 2 this.name = { 3 ‘first’:first, 4 ‘last’:last 5 }; 6 this.age = age; 7 this.gender = gender; 8 this.interests = interests; 9 this.bio = function() { 10 alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); 11 }; 12 this.greeting = function() { 13 alert('Hi! I\'m ' + this.name.first + '.'); 14 }; 15 }; 16
创建实例对象
1 var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
在控制台调用
>person1['age'] >person1.interests[1] >person1.bio() //> etc.
练习题: 我们的bio()
方法里仍有一些问题 —— 尽管您创建的Person是女性,或者是些别的性别类型,输出里的代词都总是 "He"。
而且, 纵然您有更多的兴趣列举在interests
数组中, bio只会展示您的两个兴趣。
您能想出如何在类型定义(构造函数)中解决这个问题吗?
您可以按照您喜欢的方式编写构造函数(您可能需要一些条件判断和循环)。
考虑下语句如何根据性别、兴趣列表中兴趣的数目异构。
1 <html> 2 <head> 3 <meta charset="UTF-8"> 4 <title></title> 5 </head> 6 <body> 7 <!-- 8 作者:1131681586@qq.com 9 时间:2018-03-10 10 描述: 11 要求: 12 我们的bio()方法里仍有一些问题 —— 尽管您创建的Person是女性,或者是些别的性别类型,输出里的代词都总是 "He"。 13 而且, 纵然您有更多的兴趣列举在interests数组中, bio只会展示您的两个兴趣。 14 您能想出如何在类型定义(构造函数)中解决这个问题吗? 15 您可以按照您喜欢的方式编写构造函数(您可能需要一些条件判断和循环)。 16 考虑下语句如何根据性别、兴趣列表中兴趣的数目异构 17 --> 18 <script type="text/javascript"> 19 function Person(first, last, age, gender, interests){ 20 this.name = { 21 'first':first, 22 'last':last 23 }; 24 this.age=age; 25 this.gender=gender; 26 this.interests=interests; 27 this.bio=function(){ 28 var message=this.name.first+ ' '+this.name.last + ' is ' + this.age + ' years old. ' ; 29 30 //年龄转换 31 if(this.gender==='male'||this.gender==='Male'||this.gender==='m'||this.gender==='M'){ 32 message+='He likes '; 33 }else if(this.gender==='female'||this.gender==='Female'||this.gender==='f'||this.gender==='F'){ 34 message+='She likes '; 35 }else{ 36 message+='They like '; 37 } 38 //兴趣增加,直接判断添加 39 if(this.interests.length===1){ 40 message+=this.interests[0]+'.'; 41 }else if(this.interests.length===2){ 42 message+=this.interests[0]+'and'+this.interests[1]+'.'; 43 }else{ 44 //对兴趣个数进行判断,而后添加 45 for(var i=0;i<=this.interests.length;i++){ 46 if(i===this.interests.length-1){ 47 message+=this.interests[i]+'.'; 48 break; //此时应立即结束循环,否则会再循环一次,出现undefined 49 }else{ 50 message+=this.interests[i]+', '; 51 } 52 } 53 } 54 alert(message); 55 }; 56 this.greeting = function() { 57 alert('Hi! I\'m ' + this.name.first + '.'); 58 }; 59 }; 60 var person1=new Person('Bob', 'Smith', 32, 'M', ['music', 'skiing','skatting']); //注意:是var一个person1;另外interests实例为一个数组 61 </script> 62 </body> 63 </html>
-
利用其他方法创建对象
- 利用
Object()
构造函数来创建一个新的空对象
1 /*在空对象person1中添加属性和方法*/ 2 //方法一: 3 var person1 = new Object(); //创建了一个新的空对象person1 4 person1.name = 'Chris'; 5 person1['age'] = 38; 6 person1.greeting = function() { 7 alert('Hi! I\'m ' + this.name + '.'); 8 } 9 //方法二: 10 var person1 = new Object({ 11 name : 'Chris', 12 age : 38, 13 greeting : function() { 14 alert('Hi! I\'m ' + this.name + '.'); 15 } 16 });
2.内嵌的方法create()
, 它允许您基于现有对象创建新的对象实例
输入: var person2 = Object.create(person1);
再在控制台,输入
>person2.name >person2.greeting()
缺点是比起构造函数,浏览器在更晚的时候才支持create()方法(IE9, IE8 或甚至以前相比)