美文网首页
JavaScript踩坑——继承&原型链

JavaScript踩坑——继承&原型链

作者: 当日故国在凤凰栖梧树 | 来源:发表于2017-08-29 19:53 被阅读0次

    20170825-继承&原型链

    属性

    • 自有属性

      自己定义的属性

    • 继承属性

      继承来的属性

      // 判断某个属性是否为该对象的自有属性(非继承得来)
      对象名.hasOwnProperty( '属性名' );

    对象

    在计算机科学中, 对象是指内存中的可以被 标识符 (变量、函数、属性)引用的一块区域.

    继承

    JavaScript中,子对象可以继承父对象的属性(且是单继承)

    console.log( [Object.name](http://object.name) ); // Object
    var o = new Object(); // 创建Object的子对象 o
    

    那,平时是怎么继承的呢?

    var q = {
     a: 2,
     m: function(){
     return this.a + 1;
     }
    };
    console.log( q.m() ); // 输出 3
    var p = Object.create( q ); // 用指定的原型对象及其属性方法创建新对象
    p.a = 12;
    console.log( p.m() ); // 输出 13, p 继承了 q 的 m()
    

    这就对了,父元素定义的属性,子元素可以继承,这里的 a 和 m 属性,属于继承属性

    // 构造函数
    var Student = function(name){
         [this.name](http://this.name) = name;
        this.age = 12;
    };
    // 给构造函数多赋点值
    Student.prototype = {
        hello = function(){console.log('hello' + ' ' + this.name)};
    };
    // 上面那步改变了一些不该改的东西,需要手动改回来
    Student.prototype.constructor = Student;
    
    // 或者,一次只定义一个属性,可以不修改 constructor
     [Student.prototype.tel](http://student.prototype.tel) = '';
    

    上面那张图,构造函数Student有个prototype属性,指向一个对象(Student.prototype),由 new Student 创建的对象继承 Student.prototype 里面的属性和 Student 里面的属性。但是,继承自 Student 的属性,子对象会自己创建同名属性并拷贝值,而继承自 Student.prototype 的属性,所有子对象会共享该属性,当 Student.prototype.hello 的值更改后,子对象.hello 的值也会更改。

    xiaoming —> Student.prorotype —> Object.prototype —> null

    原型链: 对象3 —> 对象1 —> Student.prototype —> Object.prototype —> null

    // 构造函数(虽然现在讨论的是对象的继承,构造函数也是可以继承的)
    var Student = function(name){
         [this.name](http://this.name) = name;
        this.age = 12;
    };
    // 给“构造函数”多赋点值
    Student.prototype = {
        hello = function(){console.log('hello' + ' ' + this.name)};
    };
    // 上面那步改变了一些不该改的东西,需要手动改回来
    // 其实修改的是 prototype对象的contructor属性,指向对象的构造函数
    Student.prototype.constructor = Student;
    
    // 创建子对象1 子对象2
    var hong = new Student('hong');
    var ming = new Student('ming');
    
    // 创建子对象3
    var mh = Object.create( hong );
    
    console.log( hong.__proto__ === Student.prototype ); 
    // true 对象 hong 的原型是 Student.prototype
    console.log( hong.__proto__ === Student );
    // false 不是 Student,继承时,对象继承的是对象
    console.log( typeof(Student.prototype) ); // object
    
    console.log( mh.__proto__ === hong ); // true 子对象的原型是父对象,父对象修改自己属性时,所有通过new创建的子对象的对应属性也会被实时修改,而修改构造函数则不行。
    // 在prototype里面覆盖构造函数的同名属性是无效的
    

    当调用子对象的属性时,会查找当前对象内有无定义,没有则沿原型链向上查找,直到找到该属性的定义,若查找到null还没找到,则返回undefined

    构造函数的继承

    // 构造函数的继承
    var Animal = function(name, age){
     this.name = name;
     this.age = age;
    }
    Animal.prototype.sayName = function(){
     console.log( this.name );
    }
    Animal.prototype.sayAge = function(){
     console.log( this.age );
    }
    
    var Dog = function(name, age, weight){
            // 继承 Animal 的两个属性
     Animal.call( this, name, age );
     this.weight = weight;
    }
    // 继承 Animal 的两个方法,必须在创建对象前继承,对象才能调用
    Dog.prototype = new Animal();
    Dog.prototype.constructor = Dog;
    Dog.prototype.lookDoor= function(){
     console.log( 'wangwangwang~~~' );
    }
    
    var Bird = function(name, age, color){
            // 继承 Animal 的两个属性
     Animal.call( this, name, age );
     this.color = color;
    }
    Bird.prototype.fly = function(){
     console.log( 'fly~~~' );
    }
    
    var dog1 = new Dog('哈士奇', 8, 10);
    var bird1 = new Bird('麻雀', 1, 'red');
    console.log( dog1 );
    console.log( bird1 );
    console.log('--------------------');
    dog1.sayName();
    

    推荐
    MDN-继承与原型链

    以上均为自学结果,欢迎各路高手指教。

    相关文章

      网友评论

          本文标题:JavaScript踩坑——继承&原型链

          本文链接:https://www.haomeiwen.com/subject/srjadxtx.html