zoukankan      html  css  js  c++  java
  • JS中的面向对象

    一、首先创建js对象的四种方式:
    1.普通模式

     var person=new Object();
    person.name="Irving";
    person.age=22;
    person.sayHi=function(){
    alert(this.name);
    }

     但是这样每次去创建一个类的对象相当的麻烦。所以有了下面的集中创建对象的模式。
    2.工厂模式

     function person(name,age){
    var p=new Object();
    p.name=name;
    p.age=age;
    p.sayHi=function(){
    alert(this.name);
    };
    return p;
    }

    这样就创建一一个person类(并不是真正意义上的方法,其实我们能看到,它只不过是一个方法,一个Object的对象的实例而已,里面所谓的属性,只不过是以Object特有的键值对的形式存在)。

     var p1 = person("Irving",22);
    var p2 = person("Irving",26);
    p1.sayHi();
    p2.sayHi();

    这个结果,应该猜都能猜出来。

    3.构造函数模式

     function person(name,age){
    this.name=name;
    this.age=age;
    this.sayHi=function(){
    alert(this.name);};
    }
    var p1 =new person("Irving",22);
    var p2 =new person("Irving",26);
    p1.sayHi();
    p2.sayHi();

    new关键字:

    • 开辟堆空间;
    • 创建对象;
    • 将构造函数作用域赋值给新对象(this就指向了该新对象);
    • 执行构造函数中的代码(为新对象添加属性);
    • 返回新对象

    4.原型模式,其实上面的集中方法都有大家看不到的缺陷。
    每个实例上都有自定义的各个方法对象,这样多个对象调用这个方法的时候就消耗内存资源。我们在想能不能让同一个类的对象都区调用同一个方法对象。这样就不会占用那么多的内存空间。
    好,这个时候prototype的好处就体现了。

    function person(name,age){
    this.name=name;
    this.age=age;
    }
    person.prototype.sayHi=function(){
    alert(this,name);
    }
    var p1 =new person("Irving",22);
    var p2 =new person("Irving",26);
    p1.sayHi();
    p2.sayHi();


    二、继承
    1.方法的继承,首先用原型模式创建一个父类。

     function Person(name,age){
    this.name=name;
    this.age=age;
    }
    Person.prototype.sayHi=function(){
    alert(this,name);
    }

    2.创建子类,

     function Student(){
    }
    Student.prototype=Person.prototype;
    var stu=new Person();

    如何判断stu继承了person?只要stu能点出sayHi这个方法出来就证明stu能够调用这个方法,也就是说继承了这个方法。

    stu.sayHi();很显然的能点出来,运行的话,会弹出undefinde,既然弹出了,就证明方法执行了,方法执行了就证明方法继承过来的,至于弹出的我们下面来解决。//这样子类student就能够继承父类的方法。

    但是这样父类的属性还没有继承过来,这个时候就需要考虑用到apply或者call方法,来改变函数的作用域了。

    我们更改下这个子类的构造函数

     function Student()
    {
    Person.apply(this,["panpan",22])
    }

    这个时候我们在执行sayhi这个方法的时候就会弹出panpan。那这个时候我们的继承就好解决了,我们可以在student这个类中传2个参数,name,age。然后在apply中的第二个参数设置为name和age的数组。  

    function Student(name, age) {
    Person.apply(this, [name, age])
    }

    好吧,我们看下完整的代码。

     function Person(name, age) {
    this.name = name;
    this.age = age;
    }
    Person.prototype.sayHi =function () {
    alert(this.name);
    }
    function Student(name, age) {
    Person.apply(this, [name, age])
    }
    Student.prototype = Person.prototype;
    var stu =new Student("Irving", "23");
    stu.sayHi();

    这样我们的继承问题就解决了。

     Student.prototype = Person.prototype;

    这个代码是把person的原型指针赋给了student的原型,也就是说我们给Student.prototype添加一个属性的时候,父类person也会具有这个属性。

     Student.prototype.eat =function () {
    alert(this.name+"跑步");
    }
    var per =new Person("Irving", 23);
    per.eat();

    但是

     var per =new Person("Irving", 23);
    per.eat();

    这个代码必须放在

     Student.prototype.eat =function () {
    alert(this.name+"我在吃饭");
    }

    之后,因为代码是从上到下执行的。

    在没有给原型指针添加属性方法的时候是没办法访问到的。
    上述的代码也就是说我们在给子类添加方法的时候,我们父类也有了这些方法,但是理论上来说对于继承是不允许这样的。
    那么我们怎么对子类添加方法而不会使父类也拥有这些方法呢。
    我们看一下,stu调用sayHi方法是怎么执行的。

    首先创建一个stu的对象,在栈上保存这个变量stu,在堆上保存new出来的对象,stu这个变量指向堆上对象的地址。当我们调用stu的sayHi方法时,首先会到student这个对象去找方法,找不到这个方法,然后去原型里面去找, 由于这个方法的原型实质上是person类的原型的地址。所有就到person类中区找,找到了就调用这个方法。
    如果我们将子类的原型指向父类的对象呢?

    Student.prototype =new Person();

    这就是所谓的原型继承。

    这里我补充下继承的几种方法,上面的内容涉及到原型继承和类继承(构造函数继承),一般的类继承会使用call\apply函数去尝试绑定一个访问关系,让子类能够访问的父类的实例属性。这里就不多说,下面介绍一种实例继承,一般是用来封装系统对象的,也可以引用到自定义对象。如下:

     function A(){
    this.x =1;
    }
    function B(){
    var aObj =new A();
    aObj.getX =function(){
    alert(aObj.x);
    }
    return aObj;
    }
    var bObj =new B();
    bObj.getX();
  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/Irving/p/2558658.html
Copyright © 2011-2022 走看看