视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript程序中实现继承特性的方式(图文教程)
2020-11-27 19:48:35 责编:小采
文档


JavaScript是一门强行声称面向对象的语言,而继承是面向对象的一大主要特性,下面是我给大家整理的,有兴趣的同学可以去看看。

概述JavaScript的所有对象,都有自己的继承链。也就是说,每个对象都继承另一个对象,该对象称为“原型”(prototype)对象。只有null除外,它没有自己的原型对象。

原型对象的重要性在于,如果A对象是B对象的原型,那么B对象可以拿到A对象的所有属性和方法。Object.getPrototypof方法用于获取当前对象的原型对象。

上面代码中,对象p就是对象obj的原型对象。

Object.create方法用于生成一个新的对象,继承指定对象。

上面代码中,新生成的obj对象的原型就是对象p。

非标准的__proto__属性(前后各两个下划线),可以改写某个对象的原型对象。但是,应该尽量少用这个属性,而是用Object.getPrototypeof()和Object.setPrototypeOf(),进行原型对象的读写操作。

上面代码通过__proto__属性,将p对象设为obj对象的原型。

下面是一个实际的例子。

上面代码中,b对象通过__proto__属性,将自己的原型对象设为a对象,因此b对象可以拿到a对象的所有属性和方法。b对象本身并没有x属性,但是JavaScript引擎通过__proto__属性,找到它的原型对象a,然后读取a的x属性。

new命令通过构造函数新建实例对象,实质就是将实例对象的原型绑定构造函数的prototype属性,然后在实例对象上执行构造函数。

原型对象自己的__proto__属性,也可以指向其他对象,从而一级一级地形成“原型链”(prototype chain)。

需要注意的是,一级级向上,在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。

this的动作指向不管this在哪里定义,使用的时候,它总是指向当前对象,而不是原型对象。

上面代码中,p对象的m方法来自它的原型对象o。这时,m方法内部的this对象,不指向o,而是指向p。

构造函数的继承这个小节介绍,如何让一个构造函数,继承另一个构造函数。

假定有一个Shape构造函数。

上面代码表示,构造函数的继承分成两部分,一部分是子类调用父类的构造方法,另一部分是子类的原型指向父类的原型。

上面代码中,子类是整体继承父类。有时,只需要单个方法的继承,这时可以采用下面的写法。

上面代码中,子类B的print方法先调用父类A的print方法,再部署自己的代码。这就等于继承了父类A的print方法。

__proto__属性__proto__属性指向当前对象的原型对象,即构造函数的prototype属性。

上面代码首先新建了一个对象obj,它的__proto__属性,指向构造函数(Object或obj.constructor)的prototype属性。所以,两者比较以后,返回true。

因此,获取实例对象obj的原型对象,有三种方法。

  • obj.__proto__

  • obj.constructor.prototype

  • Object.getPrototypeOf(obj)

  • 上面三种方法之中,前两种都不是很可靠。最新的ES6标准规定,__proto__属性只有浏览器才需要部署,其他环境可以不部署。而obj.constructor.prototype在手动改变原型对象时,可能会失效。

    上面代码中,C构造函数的原型对象被改成了p,结果c.constructor.prototype就失真了。所以,在改变原型对象时,一般要同时设置constructor属性。

    所以,推荐使用第三种Object.getPrototypeOf方法,获取原型对象。该方法的用法如下。

    可以使用Object.getPrototypeOf方法,检查浏览器是否支持__proto__属性,老式浏览器不支持这个属性。

    上面代码将一个对象的__proto__属性设为null,然后使用Object.getPrototypeOf方法获取这个对象的原型,判断是否等于null。如果当前环境支持__proto__属性,两者的比较结果应该是true。

    有了__proto__属性,就可以很方便得设置实例对象的原型了。假定有三个对象machine、vehicle和car,其中machine是vehicle的原型,vehicle又是car的原型,只要两行代码就可以设置。

    下面是一个实例,通过__proto__属性与constructor.prototype属性两种方法,分别读取定义在原型对象上的属性。

    显然,__proto__看上去更简洁一些。

    通过构造函数生成实例对象时,实例对象的__proto__属性自动指向构造函数的prototype对象。

    属性的继承属性分成两种。一种是对象自身的原生属性,另一种是继承自原型的继承属性。

    对象的原生属性对象本身的所有属性,可以用Object.getOwnPropertyNames方法获得。

    对象本身的属性之中,有的是可以枚举的(enumerable),有的是不可以枚举的。只获取那些可以枚举的属性,使用Object.keys方法。

    hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

    hasOwnProperty方法是JavaScript之中唯一一个处理对象属性时,不会遍历原型链的方法。

    对象的继承属性用Object.create方法创造的对象,会继承所有原型对象的属性。

    获取所有属性判断一个对象是否具有某个属性(不管是自身的还是继承的),使用in运算符。

    获得对象的所有可枚举属性(不管是自身的还是继承的),可以使用for-in循环。

    为了在for...in循环中获得对象自身的属性,可以采用hasOwnProperty方法判断一下。

    获得对象的所有属性(不管是自身的还是继承的,以及是否可枚举),可以使用下面的函数。

    用法如下:

    对象的拷贝如果要拷贝一个对象,需要做到下面两件事情。

    确保拷贝后的对象,与原对象具有同样的prototype原型对象。
    确保拷贝后的对象,与原对象具有同样的属性。
    下面就是根据上面两点,编写的对象拷贝的函数。

    多重继承JavaScript不提供多重继承功能,即不允许一个对象同时继承多个对象。但是,可以通过变通方法,实现这个功能。

    上面代码中,子类S同时继承了父类M1和M2。当然,从继承链来看,S只有一个父类M1,但是由于在S的实例上,同时执行M1和M2的构造函数,所以它同时继承了这两个类的方法。

    上面是我整理给大家的,希望今后会对大家有帮助。

    相关文章:

    详细介绍在JS中Map和ForEach的区别

    js装饰设计模式学习心得(详细解答)

    详解解读JS数值Number类型(图文教程)

    下载本文
    显示全文
    专题