简体   繁体   English

如何用Javascript属性修改对象

[英]How can in Javascript a property modify an object

I'm new to node.js, but wrote Javascript for many years, and I stumbled upon a pattern, that I don't understand: A Flag that sets a modifier on the object. 我是node.js的新手,但是写Java脚本已有很多年了,我偶然发现了一个我不了解的模式:一个在对象上sets a modifier Flag

For instance here socket.io docs : 例如在这里socket.io docs

Flag: 'broadcast' 标记:“广播”

Sets a modifier for a subsequent event emission that the event data will only be broadcast to every sockets but the sender. 为后续事件发出设置修饰符,该事件发出将仅向除发送方以外的所有套接字广播事件数据。

var io = require('socket.io')();
    io.on('connection', function(socket){
        socket.broadcast.emit('an event', { some: 'data' }); // everyone gets it but the sender
});

Here socket is an object, and broadcast is a property of that object, while socket.broadcast is that same object with a modifier set ?! 这里的socket是一个对象, broadcast是该对象的属性,而socket.broadcast是具有修饰符设置的同一对象?

How is it possible that accessing the property of an objet returns the object itself ? 访问对象的属性如何才能返回对象本身?

Is this a feature of Javascript that I ignored for years? 这是我多年来忽略的Javascript功能吗? Or is this some new feature of ES6 that I'm not aware of ? 还是我不知道的ES6的某些新功能? Or is this a coding pattern specific to node ? 还是这是特定于节点的编码模式?
And how does it work / is it achieved ? 以及它是如何运作的?

Edit: even though the other question is about the same exerpt in the docs, it is very different. 编辑:即使另一个问题是关于文档中相同的摘录,它是非常不同的。 My question is about the background in Javascript, while the other one is about the wording in the docs. 我的问题是关于Javascript的背景,而另一个是关于文档中的措辞。 The answers also are very different for this reason. 由于这个原因,答案也大不相同。

I saw your question and was intrigued, so had a look in the socket.io source. 我看到了您的问题,对此很感兴趣,因此可以查看socket.io源代码。

You can see the flag logic here . 您可以在这里看到标志逻辑。

flags.forEach(function(flag){
  Object.defineProperty(Socket.prototype, flag, {
    get: function() {
      this.flags[flag] = true;
      return this;
    }
  });
});

It's using a descriptor to define a property getter, which internally sets the flag and returns the object instance. 它使用描述符来定义属性获取器,该获取器在内部设置标志并返回对象实例。

Interesting stuff. 有趣的东西。

Lorenz, this is not something that is new to javascript. Lorenz,这不是javascript的新东西。 The method is able to do some mutation to its object, and then return that same object from the method that mutates it. 该方法能够对其对象进行某种突变,然后从对其进行突变的方法中返回相同的对象。 By doing this, it is possible to create a long chain of commands in order to easily accomplish a task. 通过这样做,可以创建一长串命令以便轻松完成任务。 Here is an example: 这是一个例子:

function person () {
    this.name = 'henry';
  this.withName = function (newName) {
    this.name = newName;
    return this;
  }
  this.printName = function () {
    console.log(this.name);
  }
}

var me = new person ();

me.printName();

me.withName('myNewName').printName();

me.printName();

From this example, you can see that the method "withName" mutates the object and then returns the object itself. 从此示例中,您可以看到方法“ withName”使对象发生突变,然后返回对象本身。 From this point, you can then call another one of the object's methods (ie, printName). 从这一点开始,您可以调用该对象的另一种方法(即printName)。 From this point forward, the new value of name is 'myNewName'. 从现在开始,name的新值是“ myNewName”。

Please note that this is not a good practice to mutate an object in this way. 请注意,这不是以这种方式变异对象的好习惯。 The chaining of commands is normally a good concept in functional programming, but the chaining of commands ought to be immutable. 在函数式编程中,命令链通常是一个好概念,但是命令链应该是不变的。

Therefore, the best way to utilize this concept of returning an object like the initial object from a method is to first create a copy of the initial object, then mutate the copy, then return the copy from the method. 因此,利用这种从方法返回类似初始对象之类的对象的概念的最佳方法是,首先创建初始对象的副本,然后对副本进行突变,然后从方法中返回副本。 This will make things much easier to understand and to debug. 这将使事情更容易理解和调试。

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM