美文网首页
原型链以及继承

原型链以及继承

作者: Jetsly | 来源:发表于2016-06-16 10:13 被阅读695次

原型链

原型链类似关系链,几乎所有的js对象都会有通过原型链prototype继承过来的方法或者属性,
javac#中也存在一个默认继承的对象。js通过原型链给父类增加方法和属性,
子类就会产生对应的方法和属性,类似c#的扩展方法。改变某个对象的原型链可以改变其继承的父类。

  1. 当存在创建一个Object.prototype.test=function(){}的时候,几乎所有的js对象都会存在一个test的方法。
  2. 当存在创建一个Number.prototype.test=function(){}的时候,几乎所有的js数字对象都会存在一个test的方法。
  3. 当存在创建一个String.prototype.test=function(){}的时候,几乎所有的js字符串对象都会存在一个test的方法。

其中__proto__不一定相等于prototype,
只有函数才有prototype__proto__属性,对象只有__proto__
每个对象都会在其内部初始化一个属性,就是__proto__
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,
那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__
于是就这样一直找下去

关于继承的方式

  1. 通过实例化父类设置prototype方法来继承对象的方法

    function p(){this.log=function(){}}
    function c(){}    
    c.prototype=new p //会继承p的方法
    Object.getPrototypeOf(new c);//输出 c.__proto__ 对象
    
  2. 通过实例化父类设置prototype方法来继承对象的prototype方法

    function p(){}
    p.prototype.log=function(){}
    function c(){}    
    c.prototype=new p //会继承p的方法
    Object.getPrototypeOf(new c);//输出 c.__proto__ 对象   
    
  3. 通过父类的prototype设置prototype方法来继承对象的prototype方法

    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){}    
    c.prototype=p.prototype //会继承p的prototype里面方法,不会继承logp
    c.prototype.test=function(){}
    Object.getPrototypeOf(new c);//输出 c.__proto__ 对象     
    
  4. 通过实例化父类设置子类实例化的__proto__方法来继承对象的方法

    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){}    
    var obj=new c;
    obj.__proto__=new p; //会继承p的prototype里面方法以及logp方法
    Object.getPrototypeOf(obj);//输出 c.__proto__ 对象   
    
  5. 通过改变在改变父类this的作用域的方式来执行父类方法继承父类的方法

    function p(){this.logp=function(){}}
    p.prototype.log=function(){}
    function c(){p.call(this)}    
    var obj=new c;  //只会继承logp方法
    

原型链相关的方法

  • hasOwnProperty
 Array.prototype.log=function(){}
 Array.prototype.hasOwnProperty('log') //true
 for(key in []){console.log(key)} //log

如果没有判断就会导致遍历出扩展的方法

  • defineProperty
  Object.defineProperty(object, propertyname, descriptor)

参数

object: 定义的对象
propertyname:参数名称
descriptor:定义的描述信息

descriptor

参数的键 描述 默认值
configurable 属性能否被删除或者重新定义 false
enumerable 遍历对象的时候属性是否可见 false
value 属性值,当设置后不能设置getset undefind
writable 属性能否改变
get 当获取属性的时候触发 undefind
set 当设置属性的时候触发 undefind

资料说writable默认值为false,但是当不设置这个参数的时候,value是可以改变的,持怀疑态度,求解

  var user={};
  Object.defineProperty(user, 'name', {
        get:()=>{
            console.log(`get value:${this.name}`)
            return this.name;
        },
        set:value=>{
            console.log(`set value:${value}`)
            this.name=value;
        }
  });

注:下面设置会抛出异常

  var user={};
  Object.defineProperty(user, 'name', {
        value:'johe',
        get:()=>{
            console.log(`get value:${this.name}`)
            return this.name;
        },
        set:value=>{
            console.log(`set value:${value}`)
            this.name=value;
        }
  });
  //Uncaught TypeError: Invalid property descriptor. 
  //Cannot both specify accessors and a value or writable attribute, #<Object>
  • defineProperties
    Object.defineProperties(object, props)

参数

object: 定义的对象
props: 添加的属性, keyvalue 分别Object.defineProperty 中的第二和第三个参数。

  • getPrototypeOf
    Object.getPrototypeOf("test") //String {length: 0, [[PrimitiveValue]]: ""}

返回当前对象的原型链对象

__proto__prototype的区别

  1. __proto__prototype相等的时候

     function c(){}
     c==c.prototype.constructor //true
     c==(new c).constructor //true
     (new c).__proto__===c.prototype //true
    

(new c).__proto__c.prototype,(new c).constructor.prototype都是恒等的。
一旦prototype被赋予属性和方法,那么函数创建的实例会继承prototype上的属性和方法

  1. __proto__prototype存在不相等的时候

     function c(){}
     c.prototype={
         log:function(){}
     }
     c==c.prototype.constructor //false
     c==(new c).constructor //false
     (new c).__proto__===c.prototype //true
     (new c).constructor===Object //true;
    

重写了c.prototype后,(new c).__proto__c.prototype还是恒等的,
但是c.prototype.constructor指向了Object,而不是c,因为{}默认是Object

相关文章

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

  • 继承

    原型链直接继承 原型链直接继承prototype 原型链继承_prototype属性 继承_构造函数绑定

  • JS汇总---面向对象&数组

    面向对象 js原型链的继承 静态属性怎么继承 js原型链以及特点 面向对象有哪几个特点 封装,继承,多态 对象的继...

  • 原型链以及继承

    原型链 原型链类似关系链,几乎所有的js对象都会有通过原型链prototype继承过来的方法或者属性,在java和...

  • 原型与原型链以及继承

    今天复习下原型与原型链的知识,以及记录新学的继承知识点。 知识点纲要 原型与原型链 es5与es6继承 什么是原型...

  • js中的实现继承的几种方式

    大纲:原型链借用构造函数组合继承原型式继承寄生式继承寄生组合式继承 1、原型链: 什么是原型链? 原型链的基本思想...

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • js基础之实现继承的几种方式

    js 实现继承的方式有: 原型链继承; 构造函数继承; 组合继承(原型链继承 + 构造函数继承)(最常用);(原型...

  • es5的部分继承以及es6的class

    一、JavaScript常用的原型继承方式 原型链继承 2,构造函数继承(对象冒充继承) 3,组合继承(原型链继承...

  • 构造函数原型的继承方式分析

    1.通过原型链继承 综上我们可以总结出 通过原型链来实现继承的原理通过原型链来实现继承的原理原型链继承方案中,父类...

网友评论

      本文标题:原型链以及继承

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