“解释”;“功能模式”;从书中;JavaScript:好的部分;

“解释”;“功能模式”;从书中;JavaScript:好的部分;,javascript,Javascript,这些天我在学习JS,我无法理解第52页的功能模式 功能的 到目前为止,我们看到的继承模式的一个弱点是我们没有隐私。 对象的所有属性都是可见的。我们没有私有变量,也没有 私有方法。有时这并不重要,但有时这很重要。令人沮丧的是,一些不知情的程序员采用了假装的模式 隐私。如果他们有一个想要私有化的财产,他们会给它起一个奇怪的名字,希望代码的其他用户会假装他们不能 看看那些长相古怪的成员。幸运的是,我们有一个更好的选择 模块模式的应用 我们首先创建一个生成对象的函数。我们会给它起个名字 以小写字母开头,

这些天我在学习JS,我无法理解第52页的功能模式

功能的 到目前为止,我们看到的继承模式的一个弱点是我们没有隐私。 对象的所有属性都是可见的。我们没有私有变量,也没有 私有方法。有时这并不重要,但有时这很重要。令人沮丧的是,一些不知情的程序员采用了假装的模式 隐私。如果他们有一个想要私有化的财产,他们会给它起一个奇怪的名字,希望代码的其他用户会假装他们不能 看看那些长相古怪的成员。幸运的是,我们有一个更好的选择 模块模式的应用

我们首先创建一个生成对象的函数。我们会给它起个名字 以小写字母开头,因为它不需要使用新前缀。这个 函数包含四个步骤:

  • 它会创建一个新对象。制作对象的方法有很多种。它可以成为一个 对象文本,或者它可以使用新前缀调用构造函数,或者 使用Object.beget方法从现有对象创建新实例,或 它可以调用任何返回对象的函数
  • 它可以选择定义私有实例变量和方法。这些只是普通的 函数的变量
  • 它用方法扩充了这个新对象。这些方法将具有特权 访问第二步中定义的参数和变量
  • 它返回那个新对象
  • 下面是函数构造函数的伪代码模板(为 重点):

    var构造函数=函数(规范,我的){ var,//其他私有实例变量; my=my |{}; //将共享变量和函数添加到我的 那=一个新对象; //添加特权方法 归还; } spec对象包含构造器进行分析所需的所有信息 例如。规范的内容可以复制到私有变量中或进行转换 通过其他功能。或者,这些方法可以根据需要访问spec中的信息 我需要它。(简化是用单个值替换等级库。这在以下情况下非常有用: 正在构造的对象不需要整个等级库对象。)


    有人能解释一下,那里发生了什么(用外行术语)以及这种模式在哪里有用吗?

    基本上,这个想法是在闭包中隐藏私有变量。正在关闭的变量是(未显示)“其他私有实例变量”,而实际关闭这些变量的方法是(也未显示)“特权方法”

    例如,以该函数为例:

    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;};
    }