js基础知识温习:Javascript中如何模拟私有方法
本文涉及的主题虽然很基础,在很多人眼里属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。
公有方法
公有方法就是能被外部访问并调用的方法。
// 在对象中
var Restaurant = {
name: 'McDonald',
// 公有方法
getName: function() {
return this.name;
}
}
// 在构造函数中
function Person(name, age) {
this.name = name;
this.age = age;
// 公有方法
this.getName = function() {
return this.name;
}
}
// 在原型中
Person.prototype.getAge = function() {
return this.age;
}
私有方法和特权方法
这两个方法一般放在一起讨论,原因在于我们定义的特权方法是指有权访问内部私有属性和私有方法的公有方法,而私有方法是指外部不可见且不可访问的方法。
通常定义一个对象的方式有二种,一是使用Object实例化或者对象表达式,二是使用构造函数。同样在不同的方式下面定义私有方法和特权方法的形式也不相同。
在对象中
这里我们通过Object对象表达式来创建一个对象并添加一些属性和方法,然后直接采用静态的方式调用。对象的私有数据放置在一个匿名函数立即执行表达式(IIFE)中。这意味着这个函数只存在于被调用的瞬间,一旦执行后就立即被销毁了。
在对象中创建私有数据的方式在对象的模式(指创建对象的模式)中被称之为模块模式,它的基本格式如下:
var yourObject = (function() {
// 私有属性和方法
return {
// 公有方法和属性
}
}) ();
在模块模式中,返回的对象字面量中只包含可以公开的属性和方法。
var Restaurant = (function() {
// 私有属性
var _total = 10;
// 私有方法
var _buyFood = function() {
_total--;
};
var _getTotal = function() {
return _total;
}
return {
name: 'McDonald',
getTotal: _getTotal,
buy: _buyFood
}
}) ();
Restaurant.buy();
console.log(Restaurant.name); // 'McDonald'
console.log(Restaurant.getTotal()); // 9
注意我们使用了闭包的方式来间接使用内部私有变量,同时对餐厅(Restaurant)名(name)进行了初始化。
在构造函数中
在上面介绍的模块模式创建私有方法时,公有方法和特权方法并没有什么本质上的区别,原因在于这个概念是来自于使用构造函数创建私有数据的时候定义出来的。
在构造函数中定义私有属性和方法很方便,我们不需要使用闭包,可以在调用的时候初始化数据。
function Restaurant(name) {
// 私有属性
var _total = 10;
// 公有属性
this.name = name;
// 私有方法
function _buyFood() {
_total--;
}
// 特权方法
this.buy = function() {
_buyFood();
}
this.getTotal = function() {
return _total;
}
}
// 公有方法, 注意这里不能访问私有成员_total
Restaurant.prototype.getName = function() {
console.log(_total); // Uncaught ReferenceError: _total is not defined
return this.name;
}
var McDonald = new Restaurant('McDonald');
console.log(McDonald.getName()); // 'McDonald'
McDonald.buy();
console.log(McDonald.getTotal()); // 9
合二为一,更加灵活的方式
使用模块模式我们可以多次调用,每次执行完后都会被销毁掉。使用构造函数方式可以传入一些初始化的数据,但在公有方法中无法访问到私有成员属性,如果有很多公有方法需要访问私有数据,我们全部用特权方法来写,最后会给每个实例带去很多没有必要的方法。因此,将两者结合在一起可以长短互补,结合方式也很简单
var Restaurant = (function() {
// 私有属性
var _total = 10;
// 私有方法
function _buyFood() {
_total--;
}
// 构造函数
function restaurant(name) {
this.name = name;
this.getTotal = function() {
return _total;
}
}
restaurant.prototype.buy = function() {
console.log(_total); // 10
_buyFood();
}
restaurant.prototype.getName = function() {
return this.name;
}
return restaurant;
}) ();
var McDonald = new Restaurant('McDonald');
console.log(McDonald.getName()); // 'McDonald'
McDonald.buy();
console.log(McDonald.getTotal()); // 9
总结
这个主题说实话,知识点远远不止这一点,但作者本人项目经验太少,文字功底太弱,很多东西不知道怎么描述。凑合着看一下,希望对新手有些帮助。
参考
-《JavaScript高级程序设计》(第3版)
-《JavaScript面向对象精要》
-《Effective JavaScript》
- Private Members in JavaScript
- JavaScript private methods
- AGAIN WITH THE MODULE PATTERN – REVEAL SOMETHING TO THE WORLD
js基础知识温习:Javascript中如何模拟私有方法的更多相关文章
- js基础知识温习:js中的对象
在JavaScript中对象是一个无序属性的集合,其属性可以包含基本值.对象或者函数. 对象最简单的创建方式 JavaScript中创建对象最简单的方式就是创建一个Object对象的实例,然后再添加属 ...
- js基础知识温习:构造函数与原型
构造函数 构造函数主要用于初始化新对象.按照惯例,构造函数名第一个字母都要大写. 构造函数有别于其它函数在于它使用new操作符来调用生成一个实例对象.换句话说,如果一个函数使用new操作符来调用,则将 ...
- JS基础知识:Javascript事件触发列表
Javascript是一种由Netscape的LiveScript发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言. JavaScript使我们有能 ...
- 【javascript基础知识】javascript中的转义序列和特殊数值常量
javascript的转义序列 \0 NUL字符(\u0000) \b 退格符(\u0008) \t 水平制表符(\u0009) \n 换行符(\u000A) \v 垂直制表符(\u000B) \f ...
- Javascript 基础知识学习--javascript中的参数传递都是按值传递的
ECMAScript中所有函数的参数传递都是按值传递的,无论参数是值类型还是引用类型的.过去我跟大多数人一样觉得跟传值类型相关. 自己写了一个测试的例子,确实如此 function add(a) { ...
- php面向对象基础知识整理之类中的属性和方法的使用
<?php /** * class Index * 类包含什么 * 1.创建类 * 2.类的属性和类中方法 * 3.类中访问修饰符 * 4.类的封装.继承.多态 */ // 创建类,创建的类名是 ...
- Node.js基础知识
Node.js入门 Node.js Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始.比较独特的是,Node.js会假设在POSIX环境下运行 ...
- 网站开发进阶(十五)JS基础知识充电站
JS基础知识充电站 1.javascript alert弹出对话框时确定和取消两个按钮返回值? 用的不是alert对话框,是confirm confirm(str); 参数str:你要说的话或问题: ...
- [JS复习] JS 基础知识
项目结尾,空闲时间,又把<JS 基础知识> 这本书过了一遍,温故知新后,很多知其然不知其所以然的内容 豁然开朗. [1. 用于范围的标签] display :inline or bloc ...
随机推荐
- MySQL数据库的导入和导出
1.导入数据库 在命令行下输入: mysql -u username -p test < /home/data/test.sql 说明: username 是 ...
- linux 中/proc 详解
proc 文件系统 在Linux中有额外的机制可以为内核和内核模块将信息发送给进程-- /proc 文件系统.最初设计的目的是允许更方便的对进程信息进行访问(因此得名),现在它被每一个有有趣的东西报告 ...
- linux编程之内存映射
一.概述 内存映射是在调用进程的虚拟地址空间创建一个新的内存映射. 内存映射分为2种: 1.文件映射 ...
- 解决Qt在openSUSE上编译出现“cannot find -lGL”错误
在openSUSE上编译QT5.4程序出现“cannot find -lGL”,就连example都无法通过编译.QT是在官网下的最新的安装包. 大体意思是,缺少qt运行时所需要的openGL库.决绝 ...
- TCP三次握手,数据传输,四次挥手
TCP包结构 一个TCP包结构如下: 一个TCP包主要由TCP包头和数据部分组成,包头固定部分为20字节,选项和数据部分根据实际情况设置为4N(N可以为0)字节. 1.16bit源端口和目的端口号,它 ...
- 关于Lucene 3.0升级到Lucene 4.x 备忘
最近,需要对项目进行lucene版本升级.而原来项目时基于lucene 3.0的,很古老的一个版本的了.在老版本中中,我们主要用了几个lucene的东西: 1.查询lucene多目录索引. 2.构建R ...
- 【温故而知新-Javascript】使用canvas元素(第一部分)
1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...
- No 'Access-Control-Allow-Origin' header is present on the requested resource.
今天做一个AJAX案例时,浏览器监控到如下错误: XMLHttpRequest cannot load http://54.169.69.60:8081/process_message. No 'Ac ...
- java-vector hashtable过时?
vector hashtable过时? 在用JAVA集合时,IDE提示 vector 以及hashtable被arraylist ,hashmap替代,而前者又是线程同步的,不知道为什么?是效率差了的 ...
- 使用xpath时出现noDefClass的错误(找不到某个类)
今天继续封装下jdom 发现jdom引用了个jaxen的jar 如果不导入这个库,使用xpath时出现noDefClass的错误(找不到某个类) 到csdn上 下了个 ok 同时研究了下List的to ...