javascript - 书中 "Functional Pattern"的解释 "JavaScript: The Good parts"

标签 javascript

这几天我在学习JS,我无法吸收the book第52页的这个功能模式。 .

Functional

One weakness of the inheritance patterns we have seen so far is that we get no privacy. All properties of an object are visible. We get no private variables and no private methods. Sometimes that doesn’t matter, but sometimes it matters a lot. In frustration, some uninformed programmers have adopted a pattern of pretend privacy. If they have a property that they wish to make private, they give it an odd looking name, with the hope that other users of the code will pretend that they cannot see the odd looking members. Fortunately, we have a much better alternative in an application of the module pattern.

We start by making a function that will produce objects. We will give it a name that starts with a lowercase letter because it will not require the use of the new prefix. The function contains four steps:

  1. It creates a new object. There are lots of ways to make an object. It can make an object literal, or it can call a constructor function with the new prefix, or it can use the Object.beget method to make a new instance from an existing object, or it can call any function that returns an object.
  2. It optionally defines private instance variables and methods. These are just ordinary vars of the function.
  3. It augments that new object with methods. Those methods will have privileged access to the parameters and the vars defined in the second step.
  4. It returns that new object.

Here is a pseudocode template for a functional constructor (boldface text added for emphasis):

var constructor = function (spec, my) {
   var that, //other private instance variables;

   my = my || {};

   // Add shared variables and functions to my 

   that = a new object; 

   // Add privileged methods to that 

   return that;
}

The spec object contains all of the information that the constructor needs to make an instance. The contents of the spec could be copied into private variables or transformed by other functions. Or the methods can access information from spec as they need it. (A simplification is to replace spec with a single value. This is useful when the object being constructed does not need a whole spec object.)

谁能解释一下,那里发生了什么(通俗地说)以及这种模式在哪里有用?

最佳答案

注意:虽然您提到的这本书确实是一本非常有用的书,但它相当古老。在最新版本的 JavaScript 中,一些“好的”(甚至是“坏的”)部分已被更好的替代品和功能所取代。

One weakness of the inheritance patterns we have seen so far is that we get no privacy. All properties of an object are visible. We get no private variables and no private methods.

Javascript 对象具有“属性”,可以是其他对象,也可以是函数。考虑:

var obj =  {a: 1, do: function(){console.log('done');} }

没有什么能阻止您调用 obj.a = 5obj.done()

但是有人可能会反驳说这不是创建对象的好方法。我们最好有一个原型(prototype)或类,我们可以从中创建新实例:

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

 }

In frustration, some uninformed programmers have adopted a pattern of pretend privacy. If they have a property that they wish to make private, they give it an odd looking name, with the hope that other users of the code will pretend that they cannot see the odd looking members.

这是对上述代码的评论。在声明 JavaScript 类或函数时,没有官方的、标准的、“傻瓜式且语法优雅” 方法来保持实例变量的私有(private)性。也就是说,这是一种声明变量的简单、干净的方法,该变量只能由该类或原型(prototype)中定义的方法访问 ( See this answer )。因此,人们遵循一些商定的模式,其中之一是在变量名称前加上 _ 前缀。这实际上没有为类实例的内部变量提供隐私。

随着 module system 的出现,可以在单独的文件/容器中编写 JavaScript 代码,并选择仅使特定对象对外界可见。 CommonJS 示例:

Animal.js:

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;

以上是其中一种声明类的私有(private)属性的方法,除非有意泄露,否则无法从外部访问该私有(private)属性。请注意对象 props 是如何不导出到外部世界的。

Fortunately, we have a much better alternative in an application of the module pattern.

您可能认为上面的模块代码实际上就是本文的意思,但上面的实现是使用最新功能的较新版本。文本中的要点说明的老派方法是公开一个对象创建者(又名工厂)功能。在创建者函数内部和创建的对象外部声明的所有内容在设计上都是私有(private)的:

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

这里的继承是调用 super 创建者并修改 super 实例:

function createDog(name, color){
   var breed = 'unknown';
   var dog = createAnimal(name);

   dog.setBreed = function(b){breed = b;};
}

关于javascript - 书中 "Functional Pattern"的解释 "JavaScript: The Good parts",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41113771/

相关文章:

Javascript正则表达式替换多个字符串?

javascript - Spring Boot/Thymeleaf - Javascript 请求和 X.509 身份验证的身份验证困难

javascript - 原生 Javascript 类似 printf 的函数

javascript - 如何使用 socket.io 从服务器调用客户端方法

javascript - JavaScript 中长构造函数的最佳实践

javascript - 如何在多个 fabric js Canvas 的情况下管理内存?

javascript - 生成的标签不加载 css

javascript - 如何将用户定义的属性传递给可能尚不存在的Javascript对象?

javascript - 如何根据是否存在另一个 CSS 类组合来更改 CSS 类?

javascript - 单击图库中的图像并在同一页面中显示多个图像