zoukankan      html  css  js  c++  java
  • 理解JavaScript原型和面向对象(继承)

    JavaScript面向对象核心知识归纳:http://duni.sinaapp.com/?p=742

    彻底理解JavaScript原型:http://www.imooc.com/article/2088

    js构造函数的方法与原型prototype:http://caibaojian.com/js-constructor-vs-prototype.html

    关于__proto__和prototype的一些理解:http://www.cnblogs.com/zzcflying/archive/2012/07/20/2601112.html

    理解JavaScript作用域和作用域链:http://www.cnblogs.com/dolphinX/p/3280876.html

    JavaScript中的this简单易懂:http://www.imooc.com/article/1758

    JavaScript中this绑定详解:http://www.html5cn.org/article-9834-1.html

    apply和call的应用与区别: http://www.html5cn.org/article-2875-1.html  

    如何编写可维护的面向对象JavaScript代码:http://saebbs.com/forum.php?mod=viewthread&tid=37721&page=1&extra=#pid254894

    js面向对象[继承]:http://www.w3cfuns.com/notes/22817/d2f3569a8e8a2db7c4d7162e96c0c7d8.html

    全面理解面向对象的JavaScript:http://caibaojian.com/javascript-object-2.html#?wb

    JavaScript中对象的7种创建方式:http://www.w3cfuns.com/notes/33204/f36b70e9910da3fc4461568fc3806ca1.html

    一道常被人轻视的前端JS面试题:http://www.cnblogs.com/xxcanghai/p/5189353.html

    前端小白如何用面向对象思想写代码:https://segmentfault.com/a/1190000008993282?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com

     

    关于JavaScript原型的概念:

    1.所有的对象都有"proto"属性,该属性对应该对象的原型
    2.所有的函数对象都有"prototype"属性,该属性的值会被赋值给该函数创建的对象的"proto"属性(当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有对象实例,就是设置实例的"proto"属性,也就是说,所有实例的原型引用的是函数的"prototype"属性)
    3.所有的原型对象都有"constructor"属性,该属性对应创建所有指向该原型的实例的构造函数

    通过一个很简单的例子来了解原型:

    function Person(name, age){ //构造函数 
      this.name = name;
      this.age = age;
    
      this.getInfo = function(){
        console.log(this.name + " is " + this.age + " years old");
        };
    }
    
    Person.prototype.Say = function () {
      alert("Person say");
    }
    var p = new Person("will", 22);
    p.Say();
    为什么p可以访问Person的Say?
    首先var p=new Person(),可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了Person.prototype.Say=function(){}; 于是,就找到了这个方法。
    
    再来看一个关于原型继承的例子:
    
    // 定义Human类
    function Human() {
      this.setName = function (fname, lname) {
      this.fname = fname;
      this.lname = lname;
    }
      this.getFullName = function () {
        return this.fname + " " + this.lname;
      };
    }
    
    // 定义Human类
    function Human() {
      this.setName = function (fname, lname) {
           this.fname = fname;
           this.lname = lname;
       }
      this.getFullName = function () {
        return this.fname + " " + this.lname;
      };
    }
    
    //定义Employee类
    function Employee(num) {
      this.getNum = function () {
        return num;
      }
    };
    //让Employee继承Human类
    Employee.prototype = new Human();
    
    //实例化Employee对象
    var john = new Employee("4815162342");
    john.setName("John", "Doe");
    alert(john.getFullName() + "'s employee number is " + john.getNum());//John Doe's employee number is 4815162342

    构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。 

    //组合使用构造函数模式和原型模式
    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    
    Person.prototype = {
      constructor: Person, //更正为正确的指向
      sayName: function(){
        alert(this.name);
      }
    };
    
    var person1 = new Person("Nicholas", 29);
    person1.sayName();//Nicholas
    console.log(person1.age);//29
    console.log(person1.constructor);//function Person(){}
    console.log(person1.__proto__);//访问person1实例的原型对象
    console.log(Person.prototype.constructor);//function Person(){}
    console.log(person1.constructor === Person.prototype.constructor);//true

    组合继承:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。

    function SuperType(name){
      this.name = name;
      this.colors = ["red", "blue", "green"];
    }
    
    SuperType.prototype.sayName = function(){
      alert(this.name);
    };
    
    function SubType(name, age){
      //继承属性
      SuperType.call(this, name);
      this.age = age;
    }
    
    //继承方法
    SubType.prototype = new SuperType();
    SubType.prototype.constructor = SubType; //更正为正确的指向
    SubType.prototype.sayAge = function(){
      alert(this.age);
    };
    
    var instance1 = new SubType("Nicholas", 29);
    instance1.colors.push("black");
    alert(instance1.colors); //"red,blue,green,black"
    instance1.sayName(); //"Nicholas"
    instance1.sayAge(); //29
    
    var instance2 = new SubType("Greg", 27);
    alert(instance2.colors); //"red,blue,green"
    instance2.sayName(); //"Greg"
    instance2.sayAge(); //27

    关于原型的继承:

    //原型继承
    function A(){
        this.name = 'world';
    }
    
    function B(){
        this.bb = "hello";
    }
    
    var a = new A();
    var b = new B();
     
    Object.setPrototypeOf(a, b);//用Object.setPrototypeOf()方法来设置对象的原型,等同于A.prototype = new B();
    a.constructor = A;//将b设置为a的原型,此处有一个问题,即a的constructor也指向了B构造函数,可能需要纠正 
    console.log(a.constructor);//hello
    
    //ES6中的类继承
    class B{
         constructor(){
             this.bb = 'hello'
         }
    }
    class A extends B{
         constructor(){
            super();
            this.name = 'world';
         }
    }
      
    var a = new A();
    console.log(a.bb + " " + a.name);//hello world
    console.log(typeof(A));//"function"
  • 相关阅读:
    js中serialize() 序列化表单时自动url编码
    Oracle账户被锁解决:ora-28000:the account is locked
    jvm(二)------各个运行时数据库常见内存溢出分析与模拟
    解决 maven构建的web项目无法在外部Tomcat中运行的问题
    java源码分析之LinkedList(转)
    ArrayList源码剖析
    详解Swing中JTree组件的功能
    java 制作QQ登录界面
    java 类与类之间的关系 及uml图
    java 限定控制台输入值的类型
  • 原文地址:https://www.cnblogs.com/gyx19930120/p/4972378.html
Copyright © 2011-2022 走看看