构建函数和对象实例
有些人认为 JavaScript 不是真正的面向对象的语言,比如它没有像许多面向对象的语言一样有用于创建 class 类的声明
JavaScript 用一种称为构建函数的特殊函数来定义对象和它们的特征。
一个简单的例子
- 1、如何通过一个普通的函数定义一个”人“
function createNewPerson(name) {
var obj = {};
obj.name = name;
obj.greeting = function () {
`alert('Hi! I\'m ' + this.name + '.');`
}
return obj;
}
- 2、您现在可以通过调用这个函数创建一个新的叫 salva 的人,在您浏览器的JavaScript console 试试 :
var salva = createNewPerson('salva');
salva.name;
salva.greeting();
- 上述代码运行良好,但是有点冗长;如果我们知道如何创建一个对象,就没有必要创建一个新的空对象并且返回它。幸好 JavaScript 通过构建函数提供了一个便捷的方法,方法如下:
function Person(name) {
this.name = name;
this.greeting = function() {
`alert('Hi! I\'m ' + this.name + '.');`
};
}
- 这个构建函数是 JavaScript 版本的类。
- 它只定义了对象的属性和方法,除了没有明确创建一个对象和返回任何值和之外,它有了您期待的函数所拥有的全部功能。
- 使用了this关键词,即无论是该对象的哪个实例被这个构建函数创建,它的 name 属性就是传递到构建函数形参name的值,它的 greeting() 方法中也将使用相同的传递到构建函数形参name的值。
- 3、一个构建函数通常是大写字母开头,这样便于区分构建函数和普通函数。
- 4、那如何调用构建函数创建新的实例呢?
var person1 = new Person('Bob');
var person2 = new Person('Sarah');
- 保存并刷新浏览器,在 console 里输入如下代码:
person1.name
person1.greeting()
person2.name
person2.greeting()
- 页面上有两个对象,每一个保存在不同的命名空间里,当您访问它们的属性和方法时,您需要使用person1或者person2来调用它们
- 尽管它们有着相同的name属性和 greeting()方法它们是各自独立的,所以相互的功能不会冲突。
- 注意它们使用的是自己的 name 值,这也是使用 this 关键字的原因,它们使用的从实参传入形参的自己的值,而不是其它的什么值。
- 5、当新的对象被创立, 变量person1与person2有效地包含了以下值:
{
name : 'Bob',
greeting : function() {
`alert('Hi! I\'m ' + this.name + '.');`
}
}
{
name : 'Sarah',
greeting : function() {
`alert('Hi! I\'m ' + this.name + '.');`
}
}
- 之所以说是“有效”, 是因为实际的方法仍然是定义在类里面, 而不是在对象实例里面, 这与我们之前说的字母意义上的对象还是有所不同的。
创建我们最终的构造函数
在开始创建Person()构造函数
function Person(first, last, age, gender, interests) {
this.name = {
`first,`
`last`
};
this.age = age;
this.gender = gender;
this.interests = interests;
this.bio = function() {
`alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');`
};
this.greeting = function() {
`alert('Hi! I\'m ' + this.name.first + '.');`
};
};
- 接下来加上这样一行代码, 用来创建它的一个对象实例:
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
- 这样,您就可以像我们定义第一个对象一样访问它的属性和方法了:
person1['age']
person1.interests[1]
person1.bio()
// etc.
进一步的练习
- 此外, 我们的bio()方法里仍有一些问题:
- (1) 尽管您创建的Person是女性,或者是些别的性别类型,输出里的代词都总是 "He"
- (2) 纵然您有更多的兴趣列举在interests数组中, bio只会展示您的两个兴趣
<script>
`function Person(first, last, age, gender, interests){`
`this.name = {`
`'first': first,`
`'last' : last`
`};`
`this.age = age;`
`this.gender = gender;`
`this.interests = interests;`
`this.bio = function(){`
`// 定义变量string存放相同部分`
`// alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old.He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');`
`var string = this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old.'`
`// 判断性别`
`var sexual;`
`if( this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M' ){`
`sexual = 'She likes ';`
`} else if( this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F' ){`
`sexual = 'He likes ';`
`} else{`
`sexual = 'They likes ';`
`}`
`// 展示多个兴趣`
`string += sexual; // 将性别加到总句子上`
`if( this.interests.length === 1 ){`
`string += this.interests[0] + '.';`
`} else if( this.interests.length === 2 ){`
`string += this.interests[0] + ' and ' + this.interests[1] + '.';`
`} else{`
`// if there are more than 2 interests, we loop through them`
`// all, adding each one to the main string followed by a comma,`
`// except for the last one, which needs an and & a full stop`
`for( var i = 0; i < interests.length; i++ ){`
`if( i === this.interests.length -1 ){ // 最后一个兴趣需要加上add以及句号`
`string += 'and ' + this.interests[i] + '.';`
`} else {`
`string += this.interests[i] + ', ';`
`}`
`}`
`}`
`};`
`// finally, with the string built, we alert() it`
`alert(string);`
`this.greeting = function(){`
`alert('Hi! I\'m ' + this.name.first + '.');`
`};`
`};`
`// 创建实例`
`var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing', 'kickboxing']);`
`</script>`
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论