一、JavaScript的对象
JavaScript的对象概念与C++/Java所谓的对象很大的区别.JavaScript的对象实际上是一个hash表,属性名就是索引的Key.JavaScript对象只有属性,所谓的方法只是类型为函数的属性罢了.
- var user = {
- name:"rucasi",
- password:"xxxx",
- login:fuction(name, password){
- return (this.name == name && this.password == password);
- }
- };
- alert(user.name);
- alert(user["password"]);
- user.login("rucasi", "xxxx");
- var user = new Object();//定义一个Object"类"的对象user
- //可以随意添加和删除user对象的属性
- user.name = "rucasi";
- user.password = "xxxx";
- user.login = function(name, password){
- if(name == this.name && password == this.password)
- return true;
- return false;
- }
- alert(user.login("rucasi", "xxxx"));//true
- delete user.password;
- alert(user.login("rucasi", "xxxx"));//false
什么是原型,或许很多人对原型的概念都弄不清.要理解原型,首先很重要的一点是要明白,原型是对象与对象间的关系,与类完全无关(C++/Java的类概念在JavaScript毫无用武之地,JavaScript中只有对象的概念).假如对象A是对象B的原型,这样的话B的__proto__属性则指向对象A.对象B会继承对象A的所有属性.当向对象B请求属性P时,系统会先查找对象B自己的属性,倘若找不到,则会去查找对象B的__proto__属性的属性,即是对象A的属性.
- var x = {name:"rucasi", password:"xxxx"};
- var y = {};
- y.__proto__ = x; //设置y的原型是x
- alert(y.name); //"rucasi"
- alert(y.password); //"xxxx"
- y.name = "lucas"; //y不可以直接修改它的原型对象属性,所以此操作将为y添加一个name属性
- alert(y.name); //"lucas" y的name属性覆盖了它的原型对象的name属性
- alert(x.name); // "rucasi" x的name属性没有被修改
三、构造函数
事实上,JavaScript的任何函数都可以当作构造函数来使用.
- function Person(name){ //Person构造函数
- this.name = name; //this引用上下文对象
- }
- function User(name, password){ //User构造函数
- this.name = name;
- this.password = password;
- }
- /*
- 每一个函数都有预定义好的prototype属性,默认值为使用此函数构造的匿名对象,
- 此匿名对象的__proto__是一个对象,而此对象的__proto__是null.
- 函数的prototype属性是用来设置使用此函数构造而成的对象的__proto__.
- */
- User.prototype = new Person("lucas");
- var user = new User("rucasi", "xxxx");
- 创建一个对象A
- 执行A.__proto__ = User.prototype操作
- 将User函数中的this指向A,并执行函数体内的语句
- 将user指向A
四、继承
通过上面构造函数的过程分析,我们会发现,JavaScript继承不一定使用原型.
- function Person(name){
- this.name = name;
- }
- function User(name, password){
- Person.call(this, name); //设置this作为Person函数的上下文对象,并调用Person函数
- this.password = password;
- }
- var user = new User("rucasi", "xxxx");
这里使用的方法就是在User函数中调用Person函数以达到继承的效果.使用这种方法还可以实现多继承,这是原型继承无法实现的.这种继承方法(姑且称之为复制继承)与原型继承最大的不同之处在于,复制继承是操作的重新执行,它通过执行"父对象"初始化必须执行的代码来继承"父对象"的所有属性,其本质是复制一个"父对象"然后在上面进行修改;而原型继承将"子对象"的内存区域跟"父对象"的内存区域分开来,"子对象"只是与"父对象"存在一个继承关系,这关系随时可以改变删除.很明显,复制继承完全没有原型继承的快速和灵活,但复制继承可以实现多继承.
要更为详细理解JavaScript的继承问题,可查看这个网页Object Hierarchy and Inheritance in JavaScript.