原型的作用:1.将公共部分放入原型中,这样构造出的多个实例对象的公共部分只会占用一个公共空间,实现数据共享和节省内存空间
2.通过原型实现继承:构造函数模拟 "类"这个面向对象的概念,JS基于对象,基于构造函数的原型对象实现继承 如何实现继承?
1.改变原型对象的指向:将子类构造函数(B)的prototype指向父类构造函数(A)的一个实例化对象(a),那么这个子类构造函数构造出的实例化对象
(b)就可以访问父类(A)的属性和方法
缺陷:由于B的prototype改变,那么保存在原来的B的prototype里的属性和方法就无法访问了,构造出的b无法获得这些属性和方法
解决方法:先进行原型指向的改变,再定义子类的原型属性和方法,这样子类后定义的原型属性和方法就定义到了父类的实例对象中
 var Person = function(name,sex){
this.name = name;
this.sex= sex;
}
Person.prototype.eat = function () {
console.log("吃");
}; var Student = function(score){
this.score = score;
};
Student.prototype.study = function () {
console.log("学习");
}; Student.prototype = new Person("xiaoming","man"); var stu = new Student(66);
stu.eat(); //可以调用
stu.study() //报错,由于改变了prototype指向,无法寻找到study这个方法

先改变原型指向,后定义原型方法:

 var Person = function(name,sex){
this.name = name;
this.sex= sex;
}
Person.prototype.eat = function () {
console.log("吃");
}; var Student = function(score){
this.score = score;
}; Student.prototype = new Person("xiaoming","man");
Student.prototype.study = function () {
console.log("学习");
}; var stu = new Student(66);
stu.eat(); //可以调用
stu.study(); //可以调用
console.log(Student.prototype);
/* name:"xiaoming"
sex:"man"
study:ƒ () 可以看出后定义的方法写入了Student.prototype即这个new Person实例化对象中了
__proto__:Object 这个隐式原型指向Person.prototype,里面有eat方法
*/

如果使用这个方式实现多代继承,那么每一代都需要先改变原型指向,在定义原型属性和方法。

如果使用这个方式实现多代继承,那么每一代都需要先改变原型指向,在定义原型属性和方法。
在新的原型链中,原本子代的构造函数的prototype消失,新的prototype即是父代的一个实例化对象。
而子代实例对象的__proto__都指向其父代的这个实例化对象,原型链就成为实例化对象之间的指向关系,直到最高级祖先的构造函数的prototype 仍然存在的问题:改变子代prototype的指向,指向父代的一个实例对象,那么这个实例对象的属性和方法就已经被初始化了,即继承过来的属性和方法是已经确定的,无法在构建子代实例化对象时重新初始化这些继承下来的属性和方法
2.借用构造函数实现继承
* 利用call方法或者apply方法借用父代的构造函数
* 在子代构造函数中添加
* 父代构造函数.call(this.父代形参列表)
* 同时也要在子代的形参列表中加入父代的形参列表
* 想当于在子代构造函数中也写了父代构造函数中的定义属性和方法的那些代码
* 所以优点:可以在子代构造函数实例化对象时自己初始化父代的属性和方法,不再是继承到固定的实现和方法
* 所以缺陷:没有在子代的原型和父代原型之间形成原型链,所以无法访问父代原型里的方法和属性
  var Person = function (name) {
this.name= name;
this.say = function () {
console.log("Hi,I am" + this.name);
};
};
Person.prototype.eat = function () {
console.log("吃");
};
Person.prototype.sex = "man"; //父代原型里的属性 var Student= function (score,name) {
this.score = score;
Person.call(this,name);
// Person.apply(this,[name]);
};
Student.prototype.test = function () {
console.log("考试");
}; var stu1 = new Student(80,"小王");
console.log(stu1.name);
stu1.say(); //可以调用父代构造函数里的的属性和方法 console.log(stu1.sex); //undefined
stu1.eat(); //报错------>无法通过借用构造函数的方法继承父类原型里的属性和方法

3.组合继承:结合以上两种方法:

*   1):改变prototype指向(这时不需要再new父代实例化对象时传入参数),子代和父代之间形成原型链,可以继承父代原型里的属性和方法
* 2):借用父代的构造函数,实现继承父代构造函数内的属性和方法,还可以在实例化子代时自己初始化这些属性和方法
    var Person = function (name) {
this.name= name;
this.say = function () {
console.log("Hi,I am" + this.name);
};
};
Person.prototype.eat = function () {
console.log("吃");
};
Person.prototype.sex = "男"; //父代原型里的属性 var Student= function (score,name) {
this.score = score;
Person.call(this,name);
// Person.apply(this,[name]);
};
Student.prototype = new Person();
Student.prototype.test = function () {
console.log("考试");
}; var stu2 = new Student(80,"小王");
console.log(stu2.name);
stu2.say(); //可以调用父代构造函数里的的属性和方法 console.log(stu2.sex);
stu2.eat(); //可以调用父代原型里的属性和方法 console.log(stu2.score);
stu2.test(); //当然可以正常调用子代的属性和方法
												

Js实现继承的方法的更多相关文章

  1. JS 实现继承的方法 ES6 and ES5

    继承 ES6 方法  (类的继承) ES6中有一个属性的 extends 语法: ​ • class Father {} ​ • class Son extends Father{} ​ 注意:是子类 ...

  2. js中继承的方法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...

  3. js 继承 对象方法与原型方法

    js函数式编程确实比很多强语言使用灵活得多,今天抽了点时间玩下类与对象方法调用优先级别,顺便回顾下继承 暂时把原型引用写成继承 先看看简单的两个继承 var Parent = function(){} ...

  4. JS中通过call方法实现继承

    原文:JS中通过call方法实现继承 讲解都写在注释里面了,有不对的地方请拍砖,谢谢! <html xmlns="http://www.w3.org/1999/xhtml"& ...

  5. 各种实现js继承的方法总结

    昨天主要介绍了原型,在js中,原型,原型链和继承是三个很重要的概念,而这几个概念也是面试中经常会被问到的问题,今天,就把昨天还没总结的原型链和继承继续做一个整理,希望大家一起学习,一起进步呀O(∩_∩ ...

  6. js各继承方法的优缺点

    在js中有很多种继承的方法,下面总结这些方法的优缺点. ####1.原型链继承 优点: 非常纯粹的继承关系,实例是子类的实例,也是父类的实例 父类新增原型方法/原型属性,子类都能访问到 简单,易于实现 ...

  7. 由js apply与call方法想到的js数据类型(原始类型和引用类型)

    原文地址:由js apply与call方法想到的js数据类型(原始类型和引用类型) js的call方法与apply方法的区别在于第二个参数的不同,他们都有2个参数,第一个为对象(即需要用对象a继承b, ...

  8. JS对象继承篇

    JS对象继承篇 ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的 原型链 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法 function Person() ...

  9. js实现继承的5种方式 (笔记)

    js实现继承的5种方式 以下 均为 ES5 的写法: js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承 ...

随机推荐

  1. laravel view not found

    在windows开发的laravel项目,部署到Linux服务器找不到视图,代码格式可能是这样的 return view('news\list'); 原因是在Linux下不能识别反斜杠路径,解决办法是 ...

  2. 某公司的U3D笔试题

    某公司的U3D笔试题   今天这套笔试题感觉做得一般. 随后是二对一的技术面试,但涉及的技术细节相对较少,更多的是对以前工作.项目经历的询问. 然后说今天先到这里,让我等通知. 我还特意问了一下,通知 ...

  3. git hub命令,上传到github

    git hub命令,上传到github   1,git  init;      初始化 2,git   config   --global   user.email  " ....@.... ...

  4. 基于stm32f427实现SVPWM控制永磁同步开环转动

    1.SVPWM原理简介 PWM(Pulse Width Modulation)脉宽调整,这是一种利用面积等效原理实现的控制技术.SVPWM(Space Vector PWM)空间矢量PWM控制,因为控 ...

  5. leetcode1:两数之和

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 实例: 给定 nums = [2, 7, 11, 15],target = ...

  6. hbase-写操作

    hbase连接过程 hbase client在写入的数据的过程中,是直接和rs进行通信的,整个的数据写入流程并不涉及到HMaster.那么client是如何找到对应的rs呢?流程如下: client从 ...

  7. APP支付(.NET版)

    ---恢复内容开始--- APP支付(.NET版) 一.   支付宝支付 1. 有一个支付账号,在蚂蚁金服开放平台中登录账号→选择“管理中心”→在“开发者中心”下选择“网页&移动应用”→然后按 ...

  8. Java 初学UDP传输

    不谈理论,先举简单例子. 发送端代码: public class UDPDemo { public static void main(String[] args) throws Exception { ...

  9. 使用C#重写网上的60行 Javascript 俄罗斯方块源码 (带注释)

    在很久很久以前,就已经看过 60行Js的俄罗斯方块源码.无奈当时能力不够看明白,当时觉得就是个神作. 现在总算有空再看了,顺便用c#实现一遍(超过60行),顺道熟悉下Js API. 网上其他博客也有分 ...

  10. java 基本原则

    开闭原则:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求. 可以通过“抽象约束.封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一 ...