JavaScript继承学习笔记【新手必看】_javascript技巧
JavaScript作为一个面向对象语言(JS是基于对象的),可以实现继承是必不可少的,但是由于本身并没有类的概念,所以不会像真正的面向对象编程语言通过类实现继承,但可以通过其他方法实现继承。实现继承的方法很多,下面就只是其中的几种。
一. 原型链继承
function Person() { //被继承的函数叫做超类型(父类,基类) this.name='mumu'; this.age='18'; } Person.prototype.name='susu';//当属性名相同时需就近原则,先在实例里面查找,没找到再到原型里找 function Worker(){ //继承的函数叫做子类型(子类,派生类) this.job='student'; } Worker.prototype=new Person();//通过原型链继承,超类型实例化后的对象实例,赋值给子类的原型属性 var p2=new Worker(); console.log(p2.name); console.log(p2 instanceof Object);//ture 所有的构造函数都继承自Object
以上实现继承关键在于:Worker.prototype=new Person(); 将Worker的原型成为Person的一个实例,通过原型链继承。
注意:在使用原型链实现继承时,不能使用对象字面量创建原型方法,因为这样会中断关系而重写原型链。
原型链继承问题:
1.出现引用共享问题,他们还是共用一个空间,子类会影响父类
function Person() { this.bodys=['eye','foot']; } function Worker(){ } Worker.prototype=new Person(); var p1=new Worker(); p1.bodys.push('hand'); var p2=new Worker(); console.log(p1.bodys); console.log(p2.bodys);
2.在创建子类型的实例时,不能像超类型的构造函数中传递参数。
那么如何解决原型链的两个问题呢?那就继续看下面的继承方式吧~
二. 借用构造函数继承(也叫对象冒充,伪造对象或经典继承)
function Person(name,age){ this.name=name; this.age=age; this.bodys=['eye','foot']; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age); this.job=job;//子类添加属性 } var p1=new Worker('mumu','18','学生'); p1.bodys.push('hand') ; var p2=new Worker(); console.log(p1.name); console.log(p2.bodys); console.log(p1.showName());
简单分析下以上使用借用构造函数的原理:Person.call(this,name,age);这句代码调用父级构造函数,继承父级属性,使用call方法调用Person构造函数改变函数执行时候的this, 这里的this-> new出来的一个Worker对象 构造函数伪装方法:把Worker传给上面的Person。
当引用类型放在构造函数里面的时候就不会被共享,所以p2不受影响。
这里借用构造函数继承方式就解决了原型链不能传递参数以及引用类型共享的问题。
小知识:call()和apply()方法可以改变函数执行的作用域, 简言之就是改变函数中this指向的内容。
call()和apply()都接受两个参数:第一个是在其中运行函数的作用域,另一个是传递的参数。
call和apply的区别就是参数的不同.
call中的参数必须是一个个枚举出来的.
apply中的参数必须是数组或者是arguments对象
那么问题来了:为什么p1.showName()结果是错误的呢?----因为借用构造函数继承方式只能继承构造函数里的属性和方法。这里也就发现了借用构造函数的一个问题。
注意:由于把方法都放在构造函数里,每次我们实例化就会分配内存空间给它造成资源的浪费,所以一般我们都是把方法放在原型里,属性放在构造函数里。
借用构造函数继承问题:
因为借用构造函数只能继承构造函数里的属性和方法,在超类型的原型中定义的方法对子类而言是不可见的,所以就相当于没有了原型。结果所有的方法都只能在构造函数里定义,因此就没有函数复用了。
那么如何解决借用构造函数所产生的问题呢?那就要看下面这种继承方式了
三. 组合继承(伪经典继承)
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age);//借用构造函数 this.job=job; } Worker.prototype=new Person();//原型链继承 var p1=new Worker('mumu','18','学生'); console.log(p1.age); p1.showName();
组合继承:将原型链与借用构造函数结合。
思路:通过使用原型链实现原型上的属性和方法继承,借用构造函数实现实例属性的继承
以上的例子Person.call(this,name,age);借用构造函数继承了属性
Worker.prototype=new Person();原型链继承了方法 , 避免了两者的缺点,融合了它们的优点,成为最常用的继承模式。
组合继承的问题:
调用两次超类型构造函数,一次是在创建子类型原型时,另一次是在子类型的构造函数内部。
要解决这个问题就要用到寄生组合式继承方式了。
四. 原型式继承
function object(proto) { function F() {} F.prototype = proto; return new F(); } var person = { name: 'mumu', friends: ['xiaxia', 'susu'] }; var anotherPerson = object(person); anotherPerson.friends.push('wen'); var yetAnotherPerson = object(person); anotherPerson.friends.push('tian'); console.log(person.friends);//["xiaxia", "susu", "wen", "tian"] console.log(anotherPerson.__proto__)//Object {name: "mumu", friends: Array[4]}
简单分析下:function object(proto)是一个临时中转函数,里面的参数proto表示将要传递进入的一个对象,F()构造函数是临时新建的对象,用来存储传递过来的对象,F.prototype = proto;将对象实例赋值给F构造函数的原型对象,最后返回传递过来的对象的对象实例。原型式继承还是会共享引用类型的属性。
五. 寄生式继承
//临时中转函数 function object(proto) { function F() {} F.prototype = proto; return new F(); } //寄生函数 function create(proto){ var f=object(proto); f.love=function(){ return this.name; } return f; } var person = { name: 'mumu', friends: ['xiaxia', 'susu'] }; var anotherPerson = create(person); console.log(anotherPerson.love());寄生组合式继承
六. 寄生组合式继承
function object(proto) { function F() {} F.prototype = proto; return new F(); } //寄生函数 function create(Person,Worker){ var f=object(Person.prototype);//创建对象 f.constructor=Worker;//调整原型构造指针,增强对象 Worker.prototype=f;//指定对象 } function Person(name,age){ this.name=name; this.age=age; } Person.prototype.showName=function(){ console.log(this.name); } function Worker(name,age,job){ Person.call(this,name,age); this.job=job; } create(Person,Worker);//寄生组合式继承 var p1=new Person('mumu','18','学生'); p1.showName();
Diese Methode ist auch die perfekteste und idealste unter den aktuellen Vererbungsmethoden.
Die oben genannten Lernhinweise zur JavaScript-Vererbung [muss für Neulinge gelesen werden] sind alle vom Herausgeber geteilten Inhalte. Ich hoffe, dass sie Ihnen eine Referenz geben können, und ich hoffe, dass Sie Script Home unterstützen.

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务
