简单理解JavaScript中的封装与继承特性


Posted in Javascript onMarch 19, 2016

JavaScript中的封装
封装简单地说就是让外界只能访问对象的共有变量和函数,隐藏细节和数据。
js中有三种方法创建对象,分别为门户大开型、用命名规范区分私有变量、闭包创建真正的私有变量三种。
1.门户大开型,是实现对象的最基础的方法,所有方法与变量都是共有的外界可以访问。

var Book = function(name){ 
  if(this.check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  this.name = name; 
} 
Book.prototype = { 
  check:function(name){ 
    if(!name){ 
      return true; 
    } 
  }, 
  getName:function(){ 
    return this.name; 
  } 
} 
 
var book = new Book("哈哈"); 
//output:哈哈 哈哈 
console.log(book.name,book.getName());

这个例子是门户大开型的典型,外界能直接访问对象的属性和方法。可以注意到属性和变量都有"this"来创建。
 
2.用命名规范区分私有变量,该方法是门户大开型的优化版本,只不过是在私有变量或方法前面用"_"区分,如果有程序员有意使用_getName()的方法来调用方法,还是无法阻止的,不是真正地将变量隐藏。
 
3.闭包创建真正的私有变量,该方法利用js中只有函数具有作用域的特性,在构造函数的作用域中定义相关变量,这些变量可以被定义域该作用域中的所有函数访问。

var Book2 = function(name){ 
  if(check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  name = name; 
  function check(name){ 
    if(!name){ 
      return true; 
    } 
  } 
  this.getName = function(){ 
    return name; 
  } 
} 
Book2.prototype = { 
  display:function(){ 
    //无法直接访问name 
    return "display:"+this.getName(); 
  } 
} 
var book2 = new Book2("哈哈"); 
//output:undefined "哈哈" "display:哈哈" 
console.log(book2.name,book2.getName(),book2.display());

 可以看到,这个例子中的结果,直接访问name会返回undefined的结果。可以看到这个例子与门户大开型的区别,门户大开型中的变量使用"this"来创建,而这个例子中使用var来创建,check函数也是如此,使得name与check函数只能在构造函数的作用域中访问,外界无法直接访问。
该方法解决了前两种方法的问题,但是也有一定的弊端。在门户大开型对象创建模式中,所有方法都创建在原型对象中,因此不管生成多少对象实例,这些方法在内存中只存在一份,而采用该方法,每生成一个新的对象都会为每个私有变量和方法创建一个新的副本,故会耗费更多的内存。

JavaScript中的继承
Book基类:

var Book = function(name){ 
  if(this.check(name)){ 
    console.log("error"); 
    throw new Error("name null"); 
  } 
  this.name = name; 
} 
Book.prototype = { 
  check:function(name){ 
    if(!name){ 
      return true; 
    } 
  }, 
  getName:function(){ 
    return this.name; 
  } 
}

继承方法:

function extend(subClz,superClz){ 
var F = function(){} 
F.prototype = superClz.prototype; 
subClz.prototype = new F(); 
subClz.prototype.constructor = subClz; 
subClz.superClass = superClz.prototype; 
if(superClz.prototype.constructor == Object.prototype.constructor){ 
  superClz.prototype.constructor = superClz; 
}

 
使用空函数F作为桥接,可以避免直接实例化父类时调用父类的构造函数带来额外开销,而且当父类的构造函数有参数时,想直接通过subClass.prototype = new superClass();实现父类构造函数的调用和原型链的继承是不行的。

subClz.superClass = superClz.prototype; 
if(superClz.prototype.constructor == Object.prototype.constructor){ 
  superClz.prototype.constructor = superClz; 
}

 
添加这三句可以避免子类继承父类写Book.call(this,name);而是简单地写ArtBook.superClass.Constructor.call(this,name)便能实现。
并且在子类重写父类方法的时候,可以调用到父类的方法:

ArtBook.prototype.getName = functiion(){ 
  return ArtBook.superClass.getName.call(this) + "!!!"; 
}

ArtBook子类:

var ArtBook = function(name,price){ 
  ArtBook.superClass.Constructor.call(this,name); 
  this.price = price; 
} 
extend(ArtBook,Book); 
ArtBook.prototype.getPrice = function(){ 
    return this.price; 
} 
ArtBook.prototype.getName = function(){ 
   return ArtBook.superClass.getName.call(this)+"!!!"; 
 }
Javascript 相关文章推荐
IE6背景图片不缓存问题解决方案及图片使用策略多个方法小结
May 14 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
Apr 25 Javascript
Jquery Mobile 自定义按钮图标
Nov 18 Javascript
jQuery插件imgPreviewQs实现上传图片预览
Jan 15 Javascript
JS实现物体带缓冲的间歇运动效果示例
Dec 22 Javascript
微信小程序 基础组件与导航组件详细介绍
Feb 21 Javascript
浅析java线程中断的办法
Jul 29 Javascript
Vue中的v-for指令不起效果的解决方法
Sep 27 Javascript
jQuery+ajax实现批量删除功能完整示例
Jun 06 jQuery
vue-cli3中配置alias和打包加hash值操作
Sep 04 Javascript
快速解决element的autofocus失效问题
Sep 08 Javascript
原生JavaScript实现贪吃蛇游戏
Nov 04 Javascript
JavaScript的函数式编程基础指南
Mar 19 #Javascript
深入解析JavaScript中函数的Currying柯里化
Mar 19 #Javascript
Linux下为Node.js程序配置MySQL或Oracle数据库的方法
Mar 19 #Javascript
分享js粘帖屏幕截图到web页面插件screenshot-paste
Aug 21 #Javascript
JQuery用户名校验的具体实现
Mar 18 #Javascript
基于javascript实现页面加载loading效果
Sep 15 #Javascript
JQuery fileupload插件实现文件上传功能
Mar 18 #Javascript
You might like
php中设置多级目录session的问题
2011/08/08 PHP
使用PHP如何实现高效安全的ftp服务器(二)
2015/12/30 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
php设计模式之迭代器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
jQuery学习笔记之jQuery的事件
2010/12/22 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
js仿百度贴吧验证码特效实例代码
2014/01/16 Javascript
jQuery插件实现静态HTML验证码校验
2015/11/06 Javascript
基于jquery实现瀑布流布局
2020/06/28 Javascript
jQuery技巧之让任何组件都支持类似DOM的事件管理
2016/04/05 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
jQuery购物网页经典制作案例
2016/08/19 Javascript
JS正则表达式修饰符global(/g)用法分析
2016/12/27 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
2019/05/23 Javascript
基于python socketserver框架全面解析
2017/09/21 Python
python操作excel的方法
2018/08/16 Python
基于python中theano库的线性回归
2018/08/31 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
Python中使用__new__实现单例模式并解析
2019/06/25 Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
2020/02/07 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
2020/04/07 Python
详解BeautifulSoup获取特定标签下内容的方法
2020/12/07 Python
CSS3 绘制BMW logo实的现代码
2013/04/25 HTML / CSS
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
波兰最大的宠物用品网上商店:FERA.PL
2019/08/11 全球购物
ZWILLING双立人法国网上商店:德国刀具锅具厨具品牌
2019/08/28 全球购物
工程建设实施方案
2014/03/14 职场文书
爽歪歪广告词
2014/03/20 职场文书
校长寄语大全
2014/04/09 职场文书
森林病虫害防治方案
2014/06/02 职场文书
施工安全协议书范本
2014/09/26 职场文书
向国旗敬礼活动总结
2014/09/27 职场文书
社区党员干部承诺书
2015/05/04 职场文书
SQLServer中JSON文档型数据的查询问题解决
2021/06/27 SQL Server
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP