前  言

 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. mysql初学,mysql修改,mysql查找,mysql删除,mysql基本命令

    Mysql 下载地址https://dev.mysql.com/downloads/mysql/ 1.连接Mysql格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYS ...

  2. 防止fixed元素遮挡其他元素的方法

    有多个页面,有的有固定的头部(设置了postion:fixed的元素),有的没有固定的头部,这时就有个问题,有固定头部的页面,头部会遮挡下面的内容,那怎么解决呢? <!DOCTYPE html& ...

  3. Mac Intellij Debug 模式

    前言:本文的核心是记录debug的使用,与具体的操作系统无关. 1.什么是Debug Debug是程序的一种运行模式.用来发掘程序的走向,以及程序在运行过程中参数的变化. 2.Debug的作用 deb ...

  4. 【2017集美大学1412软工实践_助教博客】团队作业4——第一次项目冲刺(Alpha版本)小组 成绩

    第四次团队作业成绩公布 题目 团队作业4: http://www.cnblogs.com/happyzm/p/6722264.html 团队成绩 成绩公示如下: 检查项 会议内容 代码签入 心得体会或 ...

  5. 201521123042 《java程序设计》 第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. ①泛型定义:泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展, ...

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

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过? ...

  7. 201521123086《JAVA程序设计》第一周学习总结

    本周学习总结 (1)初步了解java程序的运行环境,通过命令行语句编译简单的java程序 (2)使用notepad编写,cmd下进入文件夹编译程序 (3)学习使用各种快捷键补全代码 (4)能够区别jd ...

  8. Java 第十四周总结

    1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 2. 使用JDBC连接数据库与Statement 2.1 使用Statement操作数据库.(粘贴一段你认为比较有价值的代码,出现学 ...

  9. JAVA课程设计猜数游戏 个人

    1.团队课程设计博客链接 https://i.cnblogs.com/EditPosts.aspx?postid=7067843&update=1 2.个人负责模块说明 输入用户ID 2.主要 ...

  10. 201521123011 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 协议.IP.域名.端口: 常用应用层协议:http, ftp 域名(通过域名可以找到IP)用ping测试 ...