众所周知,JavaScript中是没有传统类的概念的,js通过原型链的方式实现继承。原型是js学习中的一大重点知识,在ES6出来之前,因为js不像php、java一样拥有类的写法,所以继承方式也就不像php、java一样通过关键字extends实现子类继承父类的方式,但是js有它独特的实现继承的方式,这种方式有:prototype、原型冒充、复制继承。

1、prototype

  js中每个函数就是一个对象,每个对象都有自己的prototype属性,通过这个属性,可以指定某一类对象的原型

 function   Person(name,age,sex){
    this.name = name || " ", //设置默认值,如果传入实参,this.name的值就等于实参的值,否则this.name的值默认为 " "
    this.age = age || 24,
    this.sex = "男" || sex,
    this.say = function (){
      console.log("我会说话");
    },
    this.smile = function(){
      console.log("笑");
    },
    this.walk = function(){
      console.log("走路");
    }
  }; function Monkey(){
this.type = "monkey";
};
var oop = new Person();
Monkey.prototype = oop;
var oom = new Monkey();
//执行oom.say()输出 我会说话
oom.say();

oom对象并没有say()方法,为什么程序没有保存而且控制台还输出了 “我会说话”。因为oom对象的构造函数的prototype属性指向oop对象,表明由Monkey构造函数创建出来的一类对象,他们都具有共同的原型:oop对象。所以oom对象调用say()方法中,程序会默认先在oom对象中查找,如果没有找到这个属性,程序会沿着原型链往上寻找该属性。

需要注意的是,js中new  构造函数()这个过程发生了如下的操作:

a、创建空对象 { };

b、this指向空对象{ };

c、执行构造函数的函数体。

在过程c中,如果你熟悉js的为对象添加属性的方式(对象名 属性),你会发现,过程c其实就是给这个空对象添加属性和方法的过程。

构造函数名 。prototype = 对象 ,这个对象也可以是自定义的对象,在这个对象中定义了需要用到的方法和值。如下例子所示:

function   op(){
  a = 3;
}; var obj = {
  para : 1,
  say : function(){console.log("obj");}
};
//指定构造函数op的原型是obj对象;
op.prototype = obj; //由构造函数op创建的oop对象能够调用对象obj中的方法
var oop = new op();
oop.say();

2、原型冒充

  原型冒充的原理是通过call()与apply()函数改变当前对象的this的执行上下文。这话说的有点抽象,下面直接用例子解释:

 

 //函数
  function increase(a , b){
    return a+b;
  };   function reduce(a , b){
    return a-b;
  }
  increase . call(reduce,1,2); //输出3   reduce . call(increase,1,2); //输出-1 解释 :对象A . call(对象B , 参数1 , 参数2 , ......参数n)中执行了这样的操作: a、修改对象A的this的指向,使其暂时指向对象B,参数1与参数2是传入对象B的实参。 b、执行调用call()方法的对象。 所以increase . call(reduce,1,2); 这一句相当于increase中this指向reduce,然后执行increase(1,2),所以最终结果输出3。 //对象 function person(name){
this.name = name;
this.say = function(){
console.log(this.name);
}
};
var op = new person("张三");
op.say(); function lisi(name){
this.name = name;
};
var ls = new lisi("李四");
op.say.call(ls);//this指向ls :op.say(){ console.log(ls.name) },执行op.say()方法,输出 李四

op.say.call(ls)这句代码先是将say()函数体内的this指向ls,然后执行say()方法。op.say();这一步在正常情况下输出的结果应该是"张三",但是为什么却是“李四”了呢?原因是op.say.call(ls)这句代码将say()函数在程序解析到这句代码的位置时,this暂时指向对象ls,所以在op对象的say()体内的输出语句console.log(this.name)实际上是console.log(ls.name);

3、复制继承

  复制继承的原理是,将对象以参数的形式传递到构造函数中,在构造函数中通过对象属性的方式(Objname . propertyname或者Objname[propername])访问盖对象的属性值,将值赋予当前对象的属性。

  

function   Person(){
this.name = "张三";
this.age = 24;
this.sex = "男"
} function children(per){
this.name = per.name;
this.age = per.age;
this.sex = per.sex; }
var op = new Person();
//向children构造函数中传入op对象,在children函数内完成值的复制
var chi = new children(op);
console.log(chi.age);

以上均是js原型继承的实现方式,在js这个海洋中,因为知识有限,所以博客还存在很多不足之处,希望更够跟大家多多交流学习。

谈谈我认识的js原型的更多相关文章

  1. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  2. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  3. 【09-23】js原型继承学习笔记

    js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...

  4. js原型

    1.js基本类型和对象类型 js的简单类型包括数字(其中NaN为数字类型).字符串(类似'A'为字符,js没字符类型).布尔值.null值和undefined值.其他所有的值都是对象.数字.字符串和布 ...

  5. js原型链与继承(初体验)

    js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...

  6. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  7. js原型解析

    我们都知道javascript因为具有了继承以及变量等等一系列的特性之后才被人们认为具有一门编程语言的资格,在后续的不断发展中,js在原生的基础上扩展了基于jquery等等的库,甚至衍生了像node. ...

  8. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  9. 学习zepto.js(原型方法)

    学习zepto.js(原型方法)[1] 转载 新的一周,新的开始,今天来学习一下zepto里边的原型方法,就是通过$.进行调用的方法,也是可以通过$.fn进行扩展的方法: $.camelCase(): ...

随机推荐

  1. Lua中如何实现类似gdb的断点调试--05优化断点信息数据结构

    在上一篇04优化钩子事件处理中,我们在钩子函数中引入了call和return事件的处理,对性能进行了优化. 细心的同学可能已经发现了,我们的hook函数中call事件和line都需要对整个断点表进行遍 ...

  2. 【一】TSP、VRP、VRP模型介绍

    一. TSP问题数学模型 编辑 TSP,即Traveling Salesman Problem,也就是旅行商问题,又译为旅行推销员问题.货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求 ...

  3. 关于VBS编程初步

    VBS是基于Visual Basic的脚本语言.VBS的全称是:Microsoft Visual Basic Script Edition.用记事本就可以看到源代码.在没有语法错误的前提下,直接双击左 ...

  4. MySQL配置主从分离

    主服务器 192.168.176.110 从服务器 192.168.176.120 主数据库操作(ip:192.168.176.110)  配置MySQL主服务器的配置文件 [root@localho ...

  5. 理解 MVCC

    MongoDB.MySQL.Oracle.PostgreSQL 等事务型数据库都有 mvcc 的概念. MVCC: 即多版本并发控制,主要是为了提高数据库的读写性能,让数据库在读写的时候不用去加锁.m ...

  6. 学习SpringMVC必知必会(3)~springmvc的请求和响应

    一.处理器方法响应处理 ▷ Controller方法该怎么返回.Controller数据该怎么进行共享 返回void/ModelAndView/String 1.Controller方法返回void ...

  7. [AT2306]Rearranging(拓扑序)

    [AT2306]Rearranging(拓扑序) 只有luogu 题面(luogu): 有一个$n$个数组成的序列$a_{i}$. 高桥君会把整个序列任意排列,然后青木君可以选择两个相邻的互质的数交换 ...

  8. zookeeper从小白到精通

    目录 1.介绍 1.1概念 1.2特点 1.3主要的集群步骤 1.4数据结构 1.5应用场景 2.本地安装 2.1安装jdk 2.2下载安装 2.3配置文件修改 2.4启动服务端 2.5启动客户端 2 ...

  9. Map的野路子

    首先有一张user数据表,数据库名称为mybatis,数据如下: 我们使用以下两种方式实现数据更新的操作. 方式一 UserMapper.java如下: /** * @description: 更改用 ...

  10. 请写出你最常见到的5个runtime exception?

    对于一个有1-2年左右编程经验的人来说,总会经常遇到一些常见的异常,其中有些就是Runtime Exception.比如: NullPointerException - 当调用一个未初始化的引用变量( ...