javascript面向对象
对象的创建以及常用操作
下面的都是创建对象比较简单直观,也是JavaScript种创建对象最基本的方法,如果要创建多个对象,就会出现很多相同的代码。
1:使用new运算符(不推荐)
var user = new Object(); //使用new运算符创建一个对象
user.name = "Jack"; //给对象添加属性
user.age = 25;
user.address = "四川成都";
2:对象字面量(JSON方式)
var user = {
name:'Jack',
age:25,
address:'四川成都'
};
3:简单方式(传统赋值方式)
var user = {};
user.name = 'Jack'; //给对象添加属性
user.age = 25;
user.address = '四川成都';
4:属性的调用(对于对象属性的调用有两种方式)
(1):alert(user.name + " " +user.age);
(2):alert(user['name'] + " " +user['age']);
5:添加方法
var user = {
name:'Jack', //给对象添加属性
age:25,
address:'四川成都',
showInfo:function(){ //添加一个方法
alert(this.name+" "+this.age+" "+this.address);
},
showHello:showHello //将对象外部的方法添加到对象
};
function showHello(){
alert("Hello!");
}
user.showInfo();//调用方法
user.showHello();
工厂模式
例: function create(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.show = function () {
return this.name +' '+ this.age;
};
return obj;
}
var obj1= create('jack', 30); //第一个实例
var obj2= create('Tom', 20); //第二个实例
alert(obj1.show());
alert(obj2.show());
优点:解决了实例化时代码大量重复的问题
缺点:识别问题,它们根本无法弄清楚他们到底是哪个对象的实例
比如:
alert(typeof obj1); //Object
alert(obj1 instanceof Object); //true
构造函数(构造方法)
例: function User(name, age) { //构造函数模式
this.name = name;
this.age = age;
this.show = function () {
return this.name + ' '+this.age;
};
}
var user1 = new User('jack', 30); //第一个实例
var user2 = new User('Tom', 20); //第二个实例
优点:解决了重复实例化的问题,又解决了对象识别的问题
缺点:每个方法都要在实例上重新创建一次
Prototype原型模式
通过构造函数的弊端引出原型概念
为了讲清楚原型,我们还是必须先回顾一下构造函数的问题,用一个简单的例子再次讲解一下,我们有一只猫的构造函数,如下:
例:
function Cat(name,color){
this.name = name;
this.color = color;
}
那么现在再为这个函数添加一个不变的属性"type"(种类),再添加一个方法eat(吃老鼠)。那么,Cat就变成了下面这样:
例:
function Cat(name,color){
this.name = name;
this.color = color;
this.type = "猫科动物";
this.eat = function(){alert("吃老鼠");};
}
var cat1 = new Cat("大毛","黄色");
var cat2 = new Cat ("二毛","黑色");
alert(cat1.type); // 猫科动物
cat1.eat(); // 吃老鼠
alert(cat1.eat == cat2.eat); //false
表面上看上面的例子好像是没有什么问题,但是实际上这样做,有一个很大的弊端。那就是type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率
因此,为了让type属性和eat()方法在内存中只生成一次,然后所有实例都指向那个内存地址,引出了原型
原型:(prototype和constructor是原型最基本的概念)
原型对象实际上就是构造函数的一个实例对象,和普通的实例对象没有本质上的区别。可以包含特定类型的所有实例的共享属性或者方法。 这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做constructor的属性,指向这个函数本
比如我们简单定义一个SuperType名字的函数,里面什么属性也没有在函数内部也没有
例:
function SuperType(){
}
从下图我们看到,函数里面虽然什么都没有,但是有一个默认的prototype属性,它是一个对象,它指向的是自己的地址,而prototype这个对象本身里面又有一个属性constructor,而这个属性,又指向了函数本身,有点绕
你可以通过下面的代码做一下测试,看看效果
例:
alert(SuperType.prototype) //object
alert(SuperType.prototype.constructor) //弹出函数本身function SuperType(){}