前  言

 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。面向对象主要专注于有哪一个对象来解决这个问题,编程特点时出现一个个的类,从类中拿到对象,有这个对象去解决具体问题。 对于调用者来说,面向过程需要调用者去实现各种函数。而面向对象,只需要告诉调用者对象中的具体方法的功能, 而不需要调用者了解方法中的实现细节。

 而面向过程主要专注于如何去解决一个问题的步骤。编程特点是由一个个的函数去实现每一步的过程步骤,没有类和对象的概念。

一、 继承

我们首先解释一下继承的概念,所谓继承就是使用一个子类,继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫继承,继承的两方,发生在两个类间。

然后我们阐述一下实现继承的原理, 通过循环将父类对象的所有属性,全部赋给子类对象。关键点在于for-in循环, 即使不扩展循环Object,也能通过简单的循环实现操作

1.1扩展Object实现继承。

 function Person(name,age){
this.name=name;
this.age=age;
this.say=function(){
alert("我叫"+this.name);
}
} function Student(no){
this.no=no;
this.study=function(){
alert("我在学习");
}
} var p=new Person("张三",12);
var s=new Student("12345");
for(var i in p){
s[i]=p[i];
} Object.prototype.extend1=function(){
for(var i in parent){
this[i]=parent[i];
}
}
s.extend1(p); console.log(s);

但是呢,扩展Object继承也有如下缺点:
① 无法通过一次实例化,拿到完整的子类对象,而需要先拿到父类对象和子类对象两个对象,手动合并
② 扩展Object继承方法,也会保留在子类对象上

1.2使用原型实现继承

我们先说说使用原型继承的原理, 将父类对象,赋值给子类的prototype,那么父类对象的属性和方法就会出现在子类的prototype中。  那么,实例化子类时,子类的prototype又不会到子类对象的__proto__中,  最终,父类对象的属性和方法,会出现在子类对象的__proto__

这种继承的特点主要是,子类自身的所有属性,都是成员属性,父类继承过来的属性,都是原型属性,但是依然无法通过一次实例化拿到所有的子类对象。

 function Person(name,age){
this.name=name;
this.age=age;
this.say=function(){
alert("我叫"+this.name);
}
} function Student(no){
this.no=no;
this.study=function(){
alert("我在学习");
}
} Student.prototype=new Person("张三",12);
var s=new Student(15);
console.log(s);

1.3使用call和apply以及bind实现继承

我们先解释一下call/bind/apply三个函数的作用,这三个函数通过函数名调用这三个函数,可以强行将函数中的this指定为某个对象。

 var name="window"
function func(a,b){
console.log(this.name+a+b);
}
var obj={
name:"zhangsan"
}
var obj1={
name:"lisi"
}
func(1,2);//window12
func.call(obj,1,2);//zhangsan12
func.apply(obj1,[1,2]);//lisi12
func.bind(obj)(1,2);//zhangsan12 function Person(name,age){
this.name=name;
this.age=age;
this.say=function(){
alert("我叫"+this.name);
}
} function Student(no,name,age){
this.no=no;
this.study=function(){
alert("我在学习");
}
Person.call(this,name,age);
}
var s=new Student(12345,"张三",15);
console.log(s);

这三个函数的唯一区别,在于接受func参数列表的方式不同,除此之外,功能上无区别。

二、 封装

什么叫封装呢?封装分为方法的封装和属性的封装。
所谓 方法的封装就是将类内部的函数进行私有化处理,不对外提供调用接口,无法在类外部使用的方法,称为私有方法,即方法的封装。

而属性的封装: 将类中的属性进行私有化处理,对外不能直接使用对象名访问(私有属性)。 同时,需要提供专门用于设置和读取私有属性的set/get方法,让外部使用我们提供的方  法,对属性进行操作。 这就叫属性的封装。

封装也有需要 注意的地方, 封装不是拒绝访问,而是限制访问。  要求调用者,必须使用我们提供的set/get方法进行属性的操作,而不是直接拒绝操作。

因此,单纯的属性私有化,不能称为封装!必须要私有化之后,提供对应的set/get方法。

1、 生成实例对象的原始模式

1.1我们把人看做一个对象,人有"姓名"和"年龄"两个属性。

 var Person={

       name : "张三",

       age : "12"    

 }

1.1我们根据这个原型对象的模式,生成两个实例对象。

  var Person1= {}; // 创建一个空对象
Person1.name = "张三"; // 按照原型对象的属性赋值
Person1.age= "12";
var Person2= {};
Person2.name = "李四";
Person2.age= "15"; //这就是最简单的封装了,把两个属性封装在一个对象里面。
2、 原始对象模式的改进
  function Person(name,age) {
    return {
      name:name,
      age:age    
}
} var Person1= Person("张三","12");
var Person2= Person("李四","15");
3、 构造函数

构造函数:其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

我们来说说创建一个类和对象的大概步骤,

首先,创建一个类(构造函数):类名必须使用大驼峰法则。即每个单词首字母大写。

function 类名(属性1){
    this.属性1=属性1;
    this.方法=function(){
     //方法中要调用自身属性,必须使用this.方法
    }
   }
   通过类,实例化(new)出一个对象。
   var obj=new 类名(属性1的具体值);
   obj.属性; //调用属性
   obj.方法(); //调用方法

 //人的原型对象
function Person(name,age){
    this.name=name;
    this.age=age;
} //生成实例对象
var Person1= new Person("张三","12");
var Person2= new Person("李四","15");
console.log(Person1.name); // 张三
console.log(Person2.age); // 15 //Person1 和 Person2都会有一个constructor属性,返回当前对象的构造函数
console.log(Person1 .constructor == Person); //true
console.log(Person2 .constructor == Person); //true //instanceof检测一个对象是不是一个类的实例
console.log(Person1 instanceof Person); //true
console.log(Person2 instanceof Person); //true

构造函数需要注意以下几点,
1、通过一个类名,new出一个对象的过程,叫做"类的实例化"
2、类中的this,会在实例化的时候指向新的new出的对象
所以,this.方法this.属性,实际上是将属性和方法绑定在即将new出的对象上,在类中调用自身属性,必须使用this.属性名。如果直接使用变量名,则无法访问对应的属性。 类名必须使用大驼峰法则,注意区分与普通函数的区别。

4、 Prototype模式

prototype 属性允许您向对象添加属性和方法,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

  function Person(name,age){
this.name=name;
this.age=15;
}
Person.prototype.age=12;
var zhangsan=new Person("张三");
console.log(zhangsan.age);

编者按

  Javascript面向对象是最难的,初学者不容易掌握,可以多多参考参考专门Javascript面向对象的资料,最后,希望各位和小编一起努力,在前端的路上越走越远!

Javascript 面向对象编程—继承和封装的更多相关文章

  1. Javascript 面向对象编程1:封装

    Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,他又不是一种真正的面向对象编程语言,因为它的语法中没有class(类). 那么,如果我们要把& ...

  2. 【前端学习】javascript面向对象编程(继承和复用)

    前言       继承,代码复用的一种模式.和其它高级程序语言相比,javascript有点点不一样,它是一门纯面向对象的语言,在JS中,没有类的概念,但也可以通过原型(prototype)来模拟对象 ...

  3. 【转】Javascript 面向对象编程(一):封装

    原文链接:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html Javascript ...

  4. Javascript 面向对象编程(一):封装 by 阮一峰

    <Javascript高级程序设计(第二版)>(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Java ...

  5. (三)Javascript面向对象编程:非构造函数的继承

    Javascript面向对象编程:非构造函数的继承   这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...

  6. (二)Javascript面向对象编程:构造函数的继承

    Javascript面向对象编程:构造函数的继承   这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承 ...

  7. (一)Javascript 面向对象编程:封装

    Javascript 面向对象编程:封装 作者:阮一峰 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP ...

  8. Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)

    Javascript面向对象编程(三):非构造函数的继承   作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...

  9. Javascript面向对象编程(二):构造函数的继承 作者:yuan一峰

    Javascript面向对象编程(二):构造函数的继承   作者: 阮一峰 日期: 2010年5月23日 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生 ...

随机推荐

  1. 个人作业2——英语学习APP案例分析(必应词典的使用)

    第一部分 调研, 评测 1.使用环境:window 10 词典版本: 2.使用体验: 打开词典出现下面这一界面: 词典模块:出现了每日一词,每日一句,每日阅读板块,还提供了生词本,个人觉得最喜欢的是这 ...

  2. 联合线程(案例顾客买蛋糕 :使用join()方法)

    运行效果图:

  3. 团队作业8——第二次项目冲刺(Beta阶段)5.20

    1.当天站立式会议照片 会议内容: 本次会议为第二次会议 本次会议在陆大楼2楼召开,本次会议内容: ①:检查第一次任务完成情况 ②:做第二次任务的详细分工 ③:规定完成时间是在第三次任务之前 ④:遇到 ...

  4. Java学习3——java介绍

    Java程序运行过程: Java两种核心机制: Java虚拟机(Java Virtual Machine),提供程序运行的解释环境,使Java成为一种与平台无关的语言. Java虚拟机可以理解成一个以 ...

  5. 201521123095 《Java程序设计》第6周学习总结

    1.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖面 ...

  6. 201521123077 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 多线程 Runnable类 表示任务的类,可以当作参数传入Thread的构造器来运行该任务 Thread类 ...

  7. Java:静态内部类的使用目的、使用限制、与非静态内部类的对比

    Java之静态内部类(static class) 在一个类中创建另外一个类,叫做成员内部类.这个成员内部类可以静态的(利用static关键字修饰),也可以是非静态的. 一.静态内部类的使用目的. 在 ...

  8. JSTL常用标签

    JSTL标签常用:http://blog.csdn.net/imust_can/article/details/6965756

  9. Hibernate中fetch和lazy介绍

    fetch ,指定关联对象抓取的方式,可以设置fetch = "select" 和 fetch = "join".select方式时先查询返回要查询的主体对象( ...

  10. JavaWeb学习之JDBC API中常用的接口和类

    JDBC API中包含四个常用的接口和一个类分别是: 1.Connection接口 2.Statement接口 3.PreparedStatement接口 4.ResultSet接口 5.Driver ...