本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在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
以上就是本文的全部内容,小编只是总结了其中一小部分,还有许多未提及到的知识点,大家可以自己摸索研究,希望本文可以对初学者有所帮助。
更新动态
- 群星《2023好听新歌28》十倍音质 U盘音乐[WAV分轨][1G]
- faker拿了几个全球冠军 faker全球冠军数量介绍
- 英雄联盟faker拿了多少个冠军 Faker获得冠军数量介绍
- 英雄联盟全华班有夺冠过吗 英雄联盟全华班有没有夺过冠
- ChadCrouch-BartonCreekSoundwalk(2024)[24Bit-96kHz]FLAC
- BestAudiophileVoices4(2005)[FLAC]
- 常月《中国红》[DTS-WAV分轨]
- 国外《CS》选手抱怨上海major外设:桌子不能调节
- 美女推主COS合集图赏
- FS社母公司角川宣布:旗下共有26款游戏积极开发中!
- 黄莺莺.1984-炎夏的梦(2004环球复黑王)【宝丽金】【WAV+CUE】
- 黄雅莉.2009-雅莉不怕【福茂】【FLAC分轨】
- 张宇.1997-温古知新一个人的天荒地老【EMI百代】【WAV+CUE】
- 「灵与火的织卷」前瞻讨论开启 参与赢原石
- 【原神手游】原神基尼奇生日快乐