在面向对象的编程语言一切皆是对象。
- 创建对象的最简单方法
键/值对的方式
var hero = {
name:"GenJi"
skill:"LongJijian"
}
缺点:会产生大量重复代码
- 工厂模式创建对象
因为javascript语言并没有类的概念 所以开发人员 就用函数来封装以特定接口创建对象的细节
function createHero (name,hp,skill){
var o = new Object();
o.name = name;
o.hp = hp;
o.skill= skill;
o.sayName = function(){
alert(this.name);
};
return o;
}
var Genji = createHero("Genji",200,"longjijian");
Genji.sayName();
- 构造函数创建
function Hero (name,hp,skill){
this.name = name;
this.hp = hp;
this.skill= skill;
this.sayName = function(){
alert(this.name);
};
}
构造函数与工厂模式区别在于
没有明显的创建对象
将属性和方法赋值到this对象
没有return语句
代码量还少了(这不废话嘛)
创建对象的实例 必须使用new 操作符
var genji = new Hero("genji",200,"longjiian");
var banzang = new Hero("banzang",250,"san");
每个实例对象都有个构造函数属性 指向其构造函数
alert(genji.constructor == banzang.constructor);//true
构造函数的缺点:
构造函数的每个方法都会在实例对象上重新创建一遍 这引来的问题就是不同实例创建的同名方法不相等的。
alert(genji.sayName == banzang.sayName); //false
解决这个问题方法就是原型模式
- 原型模式
原型即prototype 是每个函数的一个属性,这个属性指向一个对象 。这个对象可以包含所有实例共享的属性和方法。简单来讲,prototype通过调用构造函数而创建那个实例的原型对象
function Hero () {
}
Hero.prototype.name = "sanmei";
Hero.prototype.hp = 200;
Hero.prototype.skill= "cuangsongmen";
Hero.prototype.sayName = function(){
alert(this.name);
};
var hero1= new Hero();
var hero2 = new Hero();
alert(hero1.sayName == hero2.sayName); //true
虽然我们无法访问到原型对象。但是javascript提供一系列方法来确定对象实例与原型对象的关系。
isPrototypeof()
alert(Hero.prototype.isPrototypeof(hero1)); //true
Oject.getPrototypeof() //返回原型对象的值
alert(Object.getprototypeof(hero1).name);
hasOwnProperty() // 实例属性返回true,原型属性 返回false
in 操作符 通过对象属性是否属与实例 是返回true 反之false
alert("name" in hero1);//true
当然现实生活中 使用原型时 往往是和构造函数组合使用 以便最大的节省内存
function Hero (name,hp,skill){
this.name = name;
this.hp = hp;
this.skill= skill;
}
Hero.Prototype.sayName = function(){
alert(this.name);
};
- 原型的使用
其实说白了原型可以为我们保存那些共同的属性和方法,以便更好的开发利用,比如我们可以为内建对象添加新的方法(例如:Array,string)
我想给Array数组添加一个叫做inArray的方法,用于查询数组某个特地的值
Array.prototype.inArray = function(value){
for (var i = 0,len = this.length;i<len;i++) {
if (this[i] == value){
return true;
}
return false;
}
}
var heros =['GENJI','BANZANG','XIAOMEI'];
alert(heros.inArray('GENJI')); //ture
alert(heros.inArray('SHANGUANG')); //false
我又想给字符串添加一个reverse方法 用于反转字符串的实现 因为在数组对象里是有reverse方法的 所以我们借助数组来实现这个功能:
String.prototype.reverse = function(){
return Array.prototype.reverse.apply(this.split('')).join('');
}
alert("ALazyPig".reverse());
使用原型扩建内建对象的却很好用, 但是使用之前还是检查一下该方法是否存在。
比如
if(!tring.prototype.reverse) {
String.prototype.reverse = function () {
return Array.prototype.reverse.apply(this.split('')).join('');
}
}
学习资料:《javascript高级程序设计 第三版》 《javascript面向对象编程指南》