热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

js面向对象之继承知识详解

web前端|js教程javascript,详解,知识web前端-js教程说到这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方

web前端|js教程js面向对象之继承知识详解
Javascript,详解,知识
web前端-js教程
说到这个继承,了解object-oriented的朋友都知道,大多oo语言都有两种,一种是接口继承(只继承方法签名);一种是实现继承(继承实际的方法)本文主要和大家介绍js面向对象之继承的相关知识,以及分享了读者弄明白这个知识点的学习心得,对此有需要的朋友参考下吧。希望能帮助到大家。
mysql源码工具,ubuntu用锐捷,蜘蛛 也叫爬虫,$x php,MIP与SEOlzw
奈何js中没有签名,因而只有实现继承,而且靠的是原型链实现的。下面正式的说一说js中继承那点事儿
hook网截源码,ubuntu键盘布局卡,python爬虫网上内容,apahce php,境外seo诈骗lzw
1、原型链
emlog博客模板源码,新版vscode改中文,ubuntu网鱼wifi,java导入tomcat,sqlite dll数据库,爬虫类宠物专卖网,php上传txt,seo.tblsc.com,在线游戏网站(魔兽世界)网页模板,app网页下载源码,bootstrap 门户模板lzw
原型链:实现继承的主要方法,利用原型让一个引用类型继承另一个引用类型的属性和方法。

回顾:构造函数,原型,实例三者的关系

每一个构造函数都有一个原型对象(Person.prototype);原型对象都包含指向构造函数的指针(constructor);每个实例都包含指向原型对象的指针(看不见的_proto_指针)

原型链是怎么来的呢?

某个构造函数的原型对象是另一个构造函数的实例;这个构造函数的原型对象就会有个(看不见的_proto_指针)指向另一个构造函数的原型对象;

那么另一个原型对象又是其他的构造函数实例又会怎么样,就这样层层递进,形成原型链;来具体看一下吧

//第一个构造函数;有一个属性和一个原型方法 function SuperType(){ this.property=true; } SuperType.prototype.getSuperValue=function(){ return this.property } //第二个构造函数;目前有一个属性 function SubType(){ this.subproperty=false } //继承了SuperType;SubType原型成了SuperType的实例;实际就是重写SubType的原型对象;给SuperType原型对象继承了 SubType.prototype=new SuperType() //现在这个构造函数有两个属性(一个本身的subproperty,一个继承的存在原型对象的property);两个方法(一个原型对象的getSubValue,一个原型对象的原型对象的getSuperValue) SubType.prototype.getSubValue=function(){ return this.subproperty } var instance=new SubType() //创建第二个构造函数的实例 console.log(instance.getSuperValue()) //true 先查找instance这个实例有没有此方法;显然没有,再查找SubType原型对象有没有此方法;也没有,再查找SubType原型对象的原型对象;显然是存在的

注意:instance的constructor现在指向的是SuperType这个构造函数;因为原来的SubType.prototype被重写了,其内部的constructor也就随着SubType.prototype的原型对象的constructor指向构造函数SuperType;至于原型搜索机制是怎么样运行的,请仔细看上面的代码,相信你是可以的

1.1完整的原型

在原型那节已经提了些,还是再说一下。完整的原型包括Object。

所有函数的默认原型都是Object的实例;每个默认原型都有个_proto_指针指向Object.prototype;因此自定义类型都继承如toString,valueOf的方法

而Object.prototype的_proto_指针指向null来结束原型链。以Person构造函数为例,看看完整的原型链图

js面向对象之继承知识详解

1.2原型和实例的关系判断

第一种使用instanceof操作符: 测试实例和原型链中出现的构造函数,结果为true

第二种使用isPrototypeOf()方法: 只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型

console.log(instance instanceof Object) //都为true console.log(instance instanceof SuperType) console.log(instance instanceof SubType) console.log(Object.prototype.isPrototypeOf(instance)) //都为true console.log(SuperType.prototype.isPrototypeOf(instance)) console.log(SubType.prototype.isPrototypeOf(instance))

1.3谨慎定义方法

注意:给原型对象添加方法,一定放在替换原型的后面,因为放在替换原型之前是找不到了,原型会被重写的;

注意:在通过原型链继承时,不能使用对象字面量创建原型方法,因为也会重写原型链;

function SuperType(){ this.property=true; } SuperType.prototype.getSuperValue=function(){ return this.property } function SubType(){ this.subproperty=false } //继承SuperType SubType.prototype=new SuperType() //使用字面量添加新方法,导致上一行无效 因为现在的原型替换了Object实例而非SuperType的实例,关系中断 SubType.prototype={ getSubValue:function(){ return this.subproperty; }, somOtherMethod:function(){ return false } }; var instance=new SubType() console.log(instance.getSuperValue()) //error

1.4原型链的问题

1、包含引用类型值的原型:当实例是另一函数的原型时,引用类型值就会变成原型上的属性,就会被另一函数的实例所共享。

function SuperType(){ this.colors=["yellow","red","olive"] } function SubType(){ } SubType.prototype=new SuperType() //color实际上就是原型上的了 var instance1=new SubType() instance1.colors.push("purple") var instance2=new SubType() console.log(instance1.colors==instance2.colors) //true

2、创建子类型实例时,不能向超类型的构造函数传递参数(没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数)

2、借助构造函数

为了解决原型中包含引用类型值带来的问题,利用构造函数来解决

在子类型构造函数的内部调用超类型构造函数(函数是特定环境中执行代码的对象,可以通过apply或call调用)

function SuperType(){ this.color=["yellow","red","olive"] } function SubType(){ //继承了SuperType SuperType.call(this) } var instance1=new SubType() instance1.color.push("purple") var instance2=new SubType() console.log(instance1.color) //["yellow","red","olive","purple"] console.log(instance2.color) //["yellow","red","olive"] //传递参数 function SuperType(name){ this.name=name } function SubType(){ SuperType.call(this,"double") this.age=12 } var instance1=new SubType() console.log(instance1.name) //double console.log(instance1.age) //12

问题:仅仅借鉴构造函数,那么避免不了构造函数的问题,方法都在构造函数定义了,函数无法复用

3、组合继承(常用的还是组合,和原型与构造结合一样)

function SuperType(name){ this.name=name; this.color=["yellow","red","olive"]; } SuperType.prototype.sayName=function(){ console.log(this.name); } function SubType(name,age){ //继承属性,创建属性副本 SuperType.call(this,name); this.age=age; } //继承属性和方法,只是原型中属性被后来的函数调用生成的属性副本遮盖 SubType.prototype=new SuperType(); alert(SubType.prototype.constructor) //指向的是SuperType SubType.prototype.cOnstructor=SubType; //将constructor回归到SubType构造函数身上 SubType.prototype.sayAge=function(){ console.log(this.age) } var instance1=new SubType("double",23) instance1.color.push("pink") console.log(instance1.color) //["yellow","red","olive","pink"] instance1.sayName() //double instance1.sayAge() //23 var instance2=new SubType("single",34) console.log(instance2.color) //["yellow","red","olive"] instance2.sayName() //single instance2.sayAge() //34

还有其他的继承,花点时间写一下

1、原型式继承

克罗克福德写的;借助原型可以基于已有的对象创建新对象,同时不必创建自定义类型

function object(o){ //本质上object()函数对其中对象的浅复制 function F(){} //创建一个新的构造函数 F.prototype=o //构造函数原型为传入的对象 return new F() //返回构造函数的实例 } var person={ name:"double", friends:["tom","jack","mike"] } var person1=object(person) //事实上为原型共享 person1.name="grey" person1.friends.push("single") console.log(person1.friends) //["tom", "jack", "mike", "single"] var person2=object(person) person2.name="red" console.log(person2.friends) //["tom", "jack", "mike", "single"]

ES5为了规范原型式的继承,有个Object.create()来方便,IE9以上可以;只是想一个对象和另一个对象保持类似的情况,完全可以这种方法

var person={ name:"double", friends:["tom","jack","mike"] } var person1=Object.create(person) person1.name="single" person1.friends.push("singles") var person2=Object.create(person) console.log(person1.friends==person2.friends) //true //Object.create()接受两个参数,一个为作为新对象原型的对象,一个为新对象定义额外属性对象 var person={ name:"double", friends:["tom","jack","mike"] } var person1=Object.create(person,{ name:{ value:"single" //每个属性都是通过自己描述符定义的 } })

2、寄生式继承

思路和原型式继承一脉相承,创建一个用于封装继承过程的函数,内部通过方式增强对象,返回对象;主要考虑对象时使用

function object(o){ function F(){} F.prototype=o return new F() } function createPerson(original){ var clOne=object(original) //继承原型 clone.sayName=function(){ alert("name") } return clone } var person={ name:"double", friends:["single","tom","jack"] } var person1=createPerson(person) person1.sayName() //name 引用类型值还是共享的

3、寄生组合继承

组合继承是继承中常常用到的,但是会调用两次超类型构造函数;寄生组合继承就是为了解决这个问题的

function object(o){ function F(){} F.prototype=o return new F() } function inheritPrototype(subType,superType){ var prototype=object(superType) //创建对象 (superType实例) prototype.cOnstructor=subType //增强对象 subType.prototype=prototype //指定对象 (原型赋予实例) } function SuperType(name,sex){ this.name=name this.sex=sex this.colors=["red"] } SuperType.prototype.sayName=function(){ alert(this.name) } function SubType(name,sex,age){ SuperType.call(this,name,sex) this.age=age } inheritPrototype(SubType,SuperType) //目前subType.prototype什么都没有 SubType.prototype.sayAge=function(){ //为subType.prototype添加个方法 alert(this.age) } var person1=new SubType("double","man",34) console.log(person1.name) //SuperType 这是个Bug console.log(person1.sex) //man console.log(person1.colors) //["red"] person1.sayAge() //34

到此,差不多结束啦,感谢你对脚本之家的支持,希望我们整理的内容能够帮助到你。

详解Javascript基于面向对象之继承_Javascript技巧


推荐阅读
  • 硬盘和内存的区别是什么?它们各有什么性能指标?
    常见问题硬盘,内存,性能指标常见问题小说导航站源码,vscode调整代码格式,ubuntu终端命名,打开和关闭tomcat,sqlite2下载安装,python爬虫解析反爬虫,ht ... [详细]
  • 后端开发|php教程public,function,protected,mdash,Jordan后端开发-php教程周五了啦啦啦啦-LAMP+PHP‘sOOP部门信息管理系统asp ... [详细]
  • jquery popupDialog 使用 加载jsp页面办法
    php教程|PHP开发jqueryphp教程-PHP开发如下所示:软件市场源码,vsCode字体不变,ubuntu的所有版本,taotomcat,sqlite连接php,个人域名服 ... [详细]
  • php实现中文文件下载
    php教程|PHP源码php实现中文文件下载php教程-PHP源码php代码爱之谷2015源码,ubuntu16桌面,tomcat9解压缩半,python爬虫带页面,php批量删除 ... [详细]
  • “近年来最大计算机漏洞”被中国程序员发现!
    头条中国程序员,计算机漏洞头条(观察者网讯)据美联社12月11日报道,中国阿里云安全团队在Web服务器软件阿帕奇(Apache)下的开源日志组件Log4j内,发现一个漏洞Log4S ... [详细]
  • 本文目录一览:1、学习Python之后可以做什么工作?有哪些方向? ... [详细]
  • 缓冲区溢出实例(一)–Windows
    一、基本概念缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获 ... [详细]
  • zend studio 9 选择自定义字体
    php教程|php手册zend,studio,选择,自定义,字体,Window,Pphp教程-php手册云监控源码,vscode下载的是zip,ubuntubios关闭,tomca ... [详细]
  • re正则表达式1.什么是正则?正则就是用一系列具有特殊含义的字符组成的规则,该规则用来描述具有某一特征的字符串。正则就是用来在一个大的字符串匹配出符合规则的子字符串2.为什么用正则 ... [详细]
  • php array_unique函数的用法?
    后端开发|PHP问题php,array_unique函数后端开发-PHP问题array_unique()是PHP中的内置函数,语法为array_unique(array,sort_ ... [详细]
  • PHP Warning: Module ‘modulename’ already loaded in问题解决办法【PHP】
    后端开发|php教程PHP,Warning,Module,modulename,already,loaded后端开发-php教程出现标题这样的错误大概是:充值网站源码,虚拟机下运行 ... [详细]
  • php 字符串分割和比较介绍
    后端开发|php教程字符串,php,介绍后端开发-php教程比较两个字符串是否相等,最常见的方法就是使用“”来判断,至于它和“”的区别,简单来说就是前者强调“Identical”类 ... [详细]
  • phpcms v9无法连接数据库怎么办
    CMS教程|PHPCMSphpcmsCMS教程-PHPCMSqq骂人源码,vscode搜索不到中文插件,ubuntu输入法下载,f14tomcat,sqliteknex,网页设计图 ... [详细]
  • win10下载速度慢
    运维|windows运维win10,下载,速度慢运维-windows运维秒赞源码详细说明,vscode怎么跑项目,台电安装ubuntu,tomcat记录请求报文,sqlite的数据 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
author-avatar
springaccounn
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有