深入浅出JavaScript的面向对象问题

一、JavaScript的对象
    JavaScript的对象概念与C++/Java所谓的对象很大的区别.JavaScript的对象实际上是一个hash表,属性名就是索引的Key.JavaScript对象只有属性,所谓的方法只是类型为函数的属性罢了.
  1. var user = {
  2.     name:"rucasi",
  3.     password:"xxxx",
  4.     login:fuction(name, password){
  5.         return (this.name == name && this.password == password);
  6.     }
  7. };
  8. alert(user.name);
  9. alert(user["password"]);
  10. user.login("rucasi""xxxx");
    JavaScript的对象可以随意添加和删除属性.
  1. var user = new Object();//定义一个Object"类"的对象user
  2. //可以随意添加和删除user对象的属性
  3. user.name = "rucasi";
  4. user.password = "xxxx";
  5. user.login = function(name, password){
  6.     if(name == this.name && password == this.password)
  7.         return true;
  8.     return false;
  9. }
  10. alert(user.login("rucasi""xxxx"));//true
  11. delete user.password;
  12. alert(user.login("rucasi""xxxx"));//false
二、原型概念
    什么是原型,或许很多人对原型的概念都弄不清.要理解原型,首先很重要的一点是要明白,原型是对象与对象间的关系,与类完全无关(C++/Java的类概念在JavaScript毫无用武之地,JavaScript中只有对象的概念).假如对象A是对象B的原型,这样的话B的__proto__属性则指向对象A.对象B会继承对象A的所有属性.当向对象B请求属性P时,系统会先查找对象B自己的属性,倘若找不到,则会去查找对象B的__proto__属性的属性,即是对象A的属性.
  1. var x = {name:"rucasi", password:"xxxx"};
  2. var y = {};
  3. y.__proto__ = x; //设置y的原型是x
  4. alert(y.name); //"rucasi"
  5. alert(y.password); //"xxxx"
  6. y.name = "lucas"//y不可以直接修改它的原型对象属性,所以此操作将为y添加一个name属性
  7. alert(y.name); //"lucas" y的name属性覆盖了它的原型对象的name属性
  8. alert(x.name); // "rucasi" x的name属性没有被修改
    原型是一种一对多的关系,就是说A可以是B的原型,也可以是C的原型,但B/C的原型只能有一个.我们会发现B/C的属性__proto__只是A的引用罢了.这样的话我们可以动态的修改B/C的__proto__属性,使得B某时刻是A的"子对象",在另一时刻却是C的"子对象".JavaScript基于原型的继承机制的灵活性就不言而喻了.

三、构造函数
    事实上,JavaScript的任何函数都可以当作构造函数来使用.
  1. function Person(name){ //Person构造函数
  2.     this.name = name; //this引用上下文对象
  3. }
  4. function User(name, password){ //User构造函数
  5.     this.name = name;
  6.     this.password = password;
  7. }
  8. /*
  9. 每一个函数都有预定义好的prototype属性,默认值为使用此函数构造的匿名对象,
  10. 此匿名对象的__proto__是一个对象,而此对象的__proto__是null.
  11. 函数的prototype属性是用来设置使用此函数构造而成的对象的__proto__.
  12. */
  13. User.prototype = new Person("lucas");
  14. var user = new User("rucasi""xxxx");
   
让我们来分析一下使用new操作生成这个user对象的过程:
  1. 创建一个对象A
  2. 执行A.__proto__ = User.prototype操作
  3. 将User函数中的this指向A,并执行函数体内的语句
  4. 将user指向A

四、继承

    通过上面构造函数的过程分析,我们会发现,JavaScript继承不一定使用原型.

  1. function Person(name){
  2.     this.name = name;
  3. }
  4. function User(name, password){
  5.     Person.call(this, name);   //设置this作为Person函数的上下文对象,并调用Person函数
  6.     this.password = password;
  7. }
  8. var user = new User("rucasi""xxxx");

    这里使用的方法就是在User函数中调用Person函数以达到继承的效果.使用这种方法还可以实现多继承,这是原型继承无法实现的.这种继承方法(姑且称之为复制继承)与原型继承最大的不同之处在于,复制继承是操作的重新执行,它通过执行"父对象"初始化必须执行的代码来继承"父对象"的所有属性,其本质是复制一个"父对象"然后在上面进行修改;而原型继承将"子对象"的内存区域跟"父对象"的内存区域分开来,"子对象"只是与"父对象"存在一个继承关系,这关系随时可以改变删除.很明显,复制继承完全没有原型继承的快速和灵活,但复制继承可以实现多继承.

    要更为详细理解JavaScript的继承问题,可查看这个网页Object Hierarchy and Inheritance in JavaScript.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值