“解释”;“功能模式”;从书中;JavaScript:好的部分;
这些天我在学习JS,我无法理解第52页的功能模式 功能的 到目前为止,我们看到的继承模式的一个弱点是我们没有隐私。 对象的所有属性都是可见的。我们没有私有变量,也没有 私有方法。有时这并不重要,但有时这很重要。令人沮丧的是,一些不知情的程序员采用了假装的模式 隐私。如果他们有一个想要私有化的财产,他们会给它起一个奇怪的名字,希望代码的其他用户会假装他们不能 看看那些长相古怪的成员。幸运的是,我们有一个更好的选择 模块模式的应用 我们首先创建一个生成对象的函数。我们会给它起个名字 以小写字母开头,因为它不需要使用新前缀。这个 函数包含四个步骤:“解释”;“功能模式”;从书中;JavaScript:好的部分;,javascript,Javascript,这些天我在学习JS,我无法理解第52页的功能模式 功能的 到目前为止,我们看到的继承模式的一个弱点是我们没有隐私。 对象的所有属性都是可见的。我们没有私有变量,也没有 私有方法。有时这并不重要,但有时这很重要。令人沮丧的是,一些不知情的程序员采用了假装的模式 隐私。如果他们有一个想要私有化的财产,他们会给它起一个奇怪的名字,希望代码的其他用户会假装他们不能 看看那些长相古怪的成员。幸运的是,我们有一个更好的选择 模块模式的应用 我们首先创建一个生成对象的函数。我们会给它起个名字 以小写字母开头,
有人能解释一下,那里发生了什么(用外行术语)以及这种模式在哪里有用吗?基本上,这个想法是在闭包中隐藏私有变量。正在关闭的变量是(未显示)“其他私有实例变量”,而实际关闭这些变量的方法是(也未显示)“特权方法” 例如,以该函数为例:
var createBoard = function (rows, cols) {
var cells = [];
var board = {};
for (var i = 0; i < rows; i++) {
cells[i] = [];
for (var j = 0; j < cols; j++) {
cells[i][j] = { player: null };
}
}
board.play = function (row, col, player) {
if (cells[row][col].player === null) {
cells[row][col].player = player;
}
};
board.getPlayer = function (row, col) {
return cells[row][col].player;
};
return board;
};
在本例中,我们返回一个board对象。棋盘内部有权访问单元格数组,但我们不允许任何人修改它,除非使用我们的两种方法,play(只有在棋盘先前未被占用时才占用棋盘空间)和getPlayer方法返回给定空间的播放器。Cells[]]对该代码的用户来说是完全隐藏的-他们不能通过直接更改我们的cell数组进行欺骗
JavaScript是基于原型的基于对象的语言,而不是基于类的语言
与基于类的面向对象语言(如PHP、Java等)相比,在这些语言中,可以定义一个类,并且成员变量可以在类内外具有各种可见性。例如,PHP设置了三个级别:public、protected或private
声明为公共的类成员可以在任何地方访问。声明为受保护的成员只能在类本身内部和由继承的类访问。声明为私有的成员只能由定义该成员的类访问
但是在JavaScript中,我们实际上没有私有变量的概念(在相同的意义上)。这就是作者在描述模块模式时所说的
因此,如果我们想在Javascript中创建一个分析性的构造,我们可以这样做:
var MyClass = function (rows, cols) {
//this could be used in prototype functions
var private = 'Private';
var members = {
public: 'Public';
getHello: function() {
return 'MyClass _ ' + private;
}
};
return members;
};
注意:虽然你提到的这本书确实是一本非常有用的书,但它非常古老。在最新版本的JavaScript中,一些“好的”(甚至是“坏的”)部分已经被更好的替代品和特性所取代
到目前为止,我们已经看到的继承模式的一个弱点是
我们没有隐私。对象的所有属性都是可见的。我们没有
私有变量和非私有方法
Javascript对象具有“属性”,可以是其他对象或函数。考虑:
var obj = {a: 1, do: function(){console.log('done');} }
没有任何东西阻止您调用obj.a=5
,或obj.done()
但有人可能会反驳说,这不是创建对象的好方法。我们最好有一个原型或类,从中我们可以创建新实例:
function Animal(name) {
this._name = name;
}
Animal.prototype.print = function(){console.log(this._name)};
或者在最新的JavaScript版本中:
class Animal {
constructor(name){
this._name = name;
}
print(){
console.log(this._name);
}
}
令人沮丧的是,一些不知情的程序员采用了
假装隐私。如果他们有自己想要的财产
二等兵,他们给它起了个奇怪的名字,希望其他人
代码的用户会假装看不到奇怪的外观
成员们
这是对上述代码的注释。在声明JavaScript类或函数时,没有官方的、标准的、“傻瓜式的、语法优雅的”保持实例变量私有的方法。也就是说,这是一种声明变量的简单、干净的方法,该变量只能由该类或原型()中定义的方法访问。因此,人们遵循一些一致同意的模式,其中之一就是在变量名称前加上\uuu
。这实际上不为类实例的内部变量提供隐私
随着的出现,人们可以在一个单独的文件/容器中编写JavaScript代码,并选择使用
var obj = {a: 1, do: function(){console.log('done');} }
function Animal(name) {
this._name = name;
}
Animal.prototype.print = function(){console.log(this._name)};
class Animal {
constructor(name){
this._name = name;
}
print(){
console.log(this._name);
}
}
const props = new WeakMap();
class Animal {
constructor(name){
props.set(this,{});
props.get(this).name = name;
}
set age(n){
props.get(this).age = age;
}
function print(){
console.log(props.get(this));
}
}
module.exports = Animal;
function createAnimal(name){
var age = 0;
var animal = {};
animal.setAge = function(a){age = a;};
animal.getName = function(){return name;};
animal.print = function(){console.log({'name':name,'age':age});};
}
function createDog(name, color){
var breed = 'unknown';
var dog = createAnimal(name);
dog.setBreed = function(b){breed = b;};
}