JavaScript 的继承机制(图文)

一、JavaScript的一些语言特性

          1.当我们声明一个函数时,实际上是定义了一个函数类型的对象。如下所示,下面三种方式定义函数对象结果是一样的。

var  func = function(){
 //....define code goes there.
}

function func ()
{
  // ...define code goes there.
}

var func  = new Function(....);

          而当我们使用它时,它会一次执行其内的代码。

          2. this 指针的作用。在函数的内部,函数的this指针的作用域是动态绑定的,即this 代表的作用域是 上面的func 变量的作用域。但是,当我们使用new func()时,此时会为函数 func 独立出一块内存区域,this 的作用域便是func自己的区域。

var func = function()
{
   this.name = "louis";
  this.age  = 22;
}
func(); //此时函数运行后,在外部window 对象可以访问name,age

var a = new func();// 此时的函数运行后,a.name,b,name.

           总结:出现上面的情况是因为函数 是一个function 类型的对象,其中,内部定义的执行语句是不可识别的,都是以字符串的形式存储在相应的区域,当我们调用它们的时候,即使用() 的时候,这时候的代码才会被拿出来,在给定的一个作用域内解析并且执行。这就是所谓的动态绑定: 即只有在运行的情况下才知道其执行的上下文。

           3.根据上面的函数的特性,我们现在定义了一个Person类 ,和一个Woman 类,由Woman类要继承Person类,我们可以在Woman内,创建一个对Person 变量的一个引用,然后执行之,这时候函数执行的上下文是Woman内部,即Person函数执行后,Person 内部的变量、属性自然隶属于 Woman 创建的对象了.

function Person()
{
        this.name="people";
       this.speak = function(){
              console.log("hello,Fellow");
       }      
}
// Woman要继承Person类
function Woman()
{
     
     this.birthe = function(){
                console.log("brithing...");
     }
}

这种继承的方式,叫做 对象冒充。

function Woman()
{
      //对象冒充方式,将函数Person动态在Woman内部执行
      this.newMethod = Person;
      this.newMethod();
      delete this.newMethod;

      this.birthe = function(){
                      console.log("birthing....");
      }     

}

二、继承的方式介绍

             1. 对象冒充(如上所述)

             image

            对象冒充可以实现多重继承:

function ClassZ() {
    this.newMethod = ClassX;
    this.newMethod();
    delete this.newMethod;

    this.newMethod = ClassY;
    this.newMethod();
    delete this.newMethod;
}

      上面的模式有个弊端,就是ClassX和ClassY 的属性定义中,如果有重复的情况,则对于继承者ClassZ而言,要看其继承顺序,后面的声明继承的类会覆盖先声明的类,即:ClassY的属性和ClassX重合的话,ClassY会覆盖ClassX内的属性。

        以对象冒充为原理,JavaScript提供了两个可以完成此继承的的方法:apply(),call();

         假设现在有对象a, 它要继承 B中的属性和方法,如下所示:

function B (words)
{
      this.name="hello";
      this.say= function(){
       console.log(words);
};

}
var a = new Object();
//a 继承B内的属性。
B.call(a,"hello");
B.apply(a,new Array("hello"));

   2. 原型模式

       在我们现实生活中,经常听到 某某东西出现了山寨货,那所谓的山寨货,则是以某个正品货为原型造出来的东西,即是仿的。javascript 内的“原型”,和这个意思差不多,都是以某一对象作为参考,进行对象的创建。故而,我们在对象的创建时,如果需要以某一对象作为原型,则如下操作:

// 设定B 以A 为原型创建
function  A()
{
      this.attr1;
      this.attr2;
      this.method1();
     ///....
}
function B()
{
}
B.prototype = new A();

var b = new B();// 继承A内所有的属性

      另外A 也可以以其它对象作为原型进行创建对象,由此,便组成了原型链:

javascript

    使用原型继承机制的一个弊端,就是B.prototype = new A(); A () 是不可以带参数的。如果使用参数,则可以使用对象冒充。

function ClassA(sColor) {
    this.color = sColor;
}

ClassA.prototype.sayColor = function () {
    alert(this.color);
};

function ClassB(sColor, sName) {
    ClassA.call(this, sColor);
    this.name = sName;
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayName = function () {
    alert(this.name);
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值