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的blockui插件显示弹出层
Apr 14 Javascript
jQuery拖动图片删除示例
May 10 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
Jun 26 Javascript
分享一款基于jQuery的视频播放插件
Oct 09 Javascript
thinkphp 表名 大小写 窍门
Feb 01 Javascript
javascript中使用正则表达式清理table样式的代码
Apr 01 Javascript
jQuery 3.0 的变化及使用方法
Feb 01 Javascript
JavaScript数组方法总结分析
May 06 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
Apr 06 Javascript
JavaScript基本语法_动力节点Java学院整理
Jun 26 Javascript
微信小程序之批量上传并压缩图片的实例代码
Jul 05 Javascript
vue实现div可拖动位置也可改变盒子大小的原理
Sep 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
星际原理概述
2020/03/04 星际争霸
web方式ftp
2006/10/09 PHP
php && 逻辑与运算符使用说明
2010/03/04 PHP
对PHP PDO的一些认识小结
2015/01/23 PHP
php生成短域名函数
2015/03/23 PHP
PHP的文件操作与算法实现的面试题示例
2015/08/10 PHP
浅析Yii2 GridView实现下拉搜索教程
2016/04/22 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
PHP实现文件上传与下载
2020/08/28 PHP
Javascript模块化编程(一)AMD规范(规范使用模块)
2013/01/17 Javascript
Jquery获取复选框被选中值的简单方法
2013/07/04 Javascript
简单学习JavaScript中的for语句循环结构
2015/11/10 Javascript
JavaScript中值类型和引用类型的区别
2017/02/23 Javascript
js中DOM三级列表(代码分享)
2017/03/20 Javascript
整理关于Bootstrap模态弹出框的慕课笔记
2017/03/29 Javascript
Vue表单验证插件的制作过程
2017/04/01 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
JS脚本实现网页自动秒杀点击
2018/01/11 Javascript
JavaScript作用域链实例详解
2019/01/21 Javascript
微信公众平台获取access_token的方法步骤
2019/03/29 Javascript
使用layer弹窗,制作编辑User信息页面的方法
2019/09/27 Javascript
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
python 写的一个爬虫程序源码
2016/02/28 Python
Python AES加密实例解析
2018/01/18 Python
Tensorflow环境搭建的方法步骤
2018/02/07 Python
Python实现图片尺寸缩放脚本
2018/03/10 Python
python实现屏保计时器的示例代码
2018/08/08 Python
Django项目中添加ldap登陆认证功能的实现
2019/04/04 Python
Python自定义聚合函数merge与transform区别详解
2020/05/26 Python
python 多线程爬取壁纸网站的示例
2021/02/20 Python
CSS3实现精美横向滚动菜单按钮
2017/04/14 HTML / CSS
德国街头和运动文化高品质商店:BSTN Store
2017/08/26 全球购物
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
英语自荐信范文
2013/12/11 职场文书
课文《燕子》教学反思
2016/02/17 职场文书
MySQL数据库完全卸载的方法
2022/03/03 MySQL