javascript 面向对象封装与继承


Posted in Javascript onNovember 27, 2014

整理一下js面向对象中的封装和继承。

1.封装

js中封装有很多种实现方式,这里列出常用的几种。

1.1 原始模式生成对象

直接将我们的成员写入对象中,用函数返回。 缺点:很难看出是一个模式出来的实例。

代码:

       function Stu(name, score) {

            return {

                name: name,

                score: score

            }

        }

        var stu1 = Stu("张三", 80);

        var stu2 = Stu("李四", 90);

        console.log(stu1.name); // 张三

1.2 生成构造模式对象

js帮我们提供了一个使用构造函数生成对象的模式,¨所谓“构造函数”,其实就是一个普通函数,但是内部使用了this变量。当使用new关键字对构造函数生成实例后,this变量则会绑定在实例对象上。

直接上代码:

      function Stu(name, score) {

            this.name = name,

            this.score = score

        }

        var stu1 = new Stu("张三", 80);

        var stu2 = new Stu("李四", 90);

        console.log(stu1.name + "/" + stu2.score); // 张三  90

        console.log((stu1.constructor == Stu) + "/" + (stu2.constructor == Stu)); // true  true

        console.log((stu1 instanceof Stu) + "/" + (stu2 instanceof Stu)); // true  true

不难看出js的构造函数生成对象和C#用class生成对象如出一辙,都是用模板定义对象成员通过new关键字实例化。

用C#代码生成同样的Stu对象

Class Stu

{
public string name;

public double score;                    

}

ok,到这儿基本的对象有了。 那么现在我们需要一个所有对象都公用的方法,而且只让这个方法创建一次。(不随着对象new而重复创建)

怎么办呢? 大家都知道在C#中我们可以用静态成员。那么在js中怎么做呢?

1.3 Prototype模式

在js中,每一个构造函数都有一个prototype属性,这个对象的所有属性和方法,都会被构造函数的实例继承。那么我们直接给prototype添加成员就相当于在C#中声明静态成员了。

代码:

      function Stu(name, score) {

            this.name = name,

            this.score = score

        }

        Stu.prototype.type='学生';

        Stu.prototype.log = function (s) {

            console.log(s);

        }

        var stu1 = new Stu("张三", 80);

        var stu2 = new Stu("李四", 90);

        console.log(stu1.type + "/" + stu2.type); // 学生 学生

        stu1.log('hello');  // hello

        console.log(stu1.log == stu2.log);  // true

封装就讲到这儿了,下面我们来看看js中继承又是如何实现的?

2.继承

2.1 构造函数绑定

在子函数中直接调用 call或apply方法,将父对象的构造函数绑定在子对象上。
 

   function Stu(name, score) {

            Grade.apply(this, arguments);

            //Grade.call(this, arguments);

            this.name = name,

            this.score = score

        }

        function Grade() {

            this.code = "初中";

            this.ask = function () {

                console.log("大家好");

            }

        }

        var stu1 = new Stu("张三", 80);

        var stu2 = new Stu("李四", 90);

        console.log(stu1.code); // 初中

        stu1.ask(); // 大家好

这里的apply做了两件事情,把第一个参数this给Grade构造函数(调用者),然后再执行Grade里的代码。就相当于将Grade中用this定义的成员在Stu中再执行一遍。

2.2 通过prototype继承

先看代码

代码:

    function Stu(name, score) {

            this.name = name,

            this.score = score

        }

        function Grade() {

            this.code = "初中";

        }

        Stu.prototype = new Grade();

        Stu.prototype.constructor = Stu; //防止继承链的紊乱,手动重置声明

        var stu1 = new Stu("张三", 80);

        var stu2 = new Stu("李四", 90);

        console.log(Stu.prototype.constructor); // 自己的构造函数

        console.log(stu1.code); // 初中

前面说过prototype就相当于C#中的静态成员,所以我们就把父类的所有成员都变成自己的静态成员来实现继承。

通过prototype继承有一个缺点:所有继承的成员都是静态的,那么怎么继承对象成员呢?

2.3 拷贝继承

把父对象的所有属性和方法,拷贝进子对象,实现继承。

代码:

    function Stu(name, score) {

            this.name = name,

            this.score = score

        }

        function Grade() {}

        Grade.prototype.code = "初中";

    }

        //函数封装

        function extend(C, P) {

            var p = P.prototype;

            var c = C.prototype;

            for (var i in p) {

                c[i] = p[i];

            }

        }

        extend(Stu, Grade);

        var stu1 = new Stu("张三", 80);

        var stu2 = new Stu("李四", 90);

        stu1.code='高中';

        console.log(stu1.code); // 高中

        console.log(stu2.code); // 初中

        console.log(Stu.prototype.constructor);

        console.log(Grade.prototype.constructor)

    js面向对象的整理就写到这了,这个东西也不是一成不变的,使用的时候根据自己的需求做改动。  有句话说的很好,合适的才是最好的。

这里只针对封装和继承进行了分析,后续我们再做一些其他方面的文章,让小伙伴们更加深入的了解javascript面向对象编程。当然都是个人的一些理解,如有遗漏,请联系我。

Javascript 相关文章推荐
jQuery之自动完成组件的深入解析
Jun 19 Javascript
浅谈JavaScript字符集
May 22 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
Jul 02 Javascript
jQuery .tmpl() 用法示例介绍
Aug 21 Javascript
Bootstrap按钮组件详解
Apr 26 Javascript
Node.js中用D3.js的方法示例
Jan 16 Javascript
js实现带三角符的手风琴效果
Mar 01 Javascript
JS实现给json数组动态赋值的方法示例
Mar 19 Javascript
vue单页应用中如何使用jquery的方法示例
Jul 27 jQuery
js禁止浏览器页面后退功能的实例(推荐)
Sep 01 Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 Javascript
JavaScript实现选项卡效果的分析及步骤
Apr 16 Javascript
javascript制作坦克大战全纪录(2)
Nov 27 #Javascript
javascript制作坦克大战全纪录(1)
Nov 27 #Javascript
使用jsonp完美解决跨域问题
Nov 27 #Javascript
JavaScript变量声明详解
Nov 27 #Javascript
js脚本实现数据去重
Nov 27 #Javascript
实例分析js和C#中使用正则表达式匹配a标签
Nov 26 #Javascript
javascript几个易错点记录
Nov 26 #Javascript
You might like
php daddslashes()和 saddslashes()有哪些区别分析
2012/10/26 PHP
php按百分比生成缩略图的代码分享
2014/05/10 PHP
php中addslashes函数与sql防注入
2014/11/17 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
PHP实现无限级分类(不使用递归)
2015/10/22 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
2015/12/24 PHP
JS实现黑客帝国文字下落效果
2015/09/01 Javascript
jquery.validate[.unobtrusive]和Bootstrap实现tooltip错误提示问题分析
2016/10/30 Javascript
浅谈jQuery操作类数组的工具方法
2016/12/23 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
2019/08/23 Javascript
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
[05:28]刀塔密之一:团结则存
2014/07/03 DOTA
python3使用pyqt5制作一个超简单浏览器的实例
2017/10/19 Python
python PyTorch预训练示例
2018/02/11 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
python3实现名片管理系统
2020/11/29 Python
python 自动重连wifi windows的方法
2018/12/18 Python
python global和nonlocal用法解析
2020/02/03 Python
Python爬虫获取豆瓣电影并写入excel
2020/07/31 Python
Python命名空间及作用域原理实例解析
2020/08/12 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
HTML5边玩边学(3)像素和颜色
2010/09/21 HTML / CSS
购房意向书
2014/04/01 职场文书
卫生系统先进事迹
2014/05/13 职场文书
医院节能减排方案
2014/06/13 职场文书
志愿者活动总结报告
2014/06/27 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
2014司机年终工作总结
2014/12/05 职场文书
计划生育个人总结
2015/03/02 职场文书
公务员处分决定书
2015/06/25 职场文书
公司管理制度范本
2015/08/03 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
领导干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
大学自主招生自荐信(2016精选篇)
2016/01/28 职场文书
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
2021/06/26 Python
聊聊配置 Nginx 访问与错误日志的问题
2022/05/25 Servers