Nodejs中bind用法求解,请大家帮帮忙

Nodejs中bind用法求解,请大家帮帮忙

最近研究pomelo,之前没接触过js,遇到bind这样的用法,完全不知所云。求解。

var onUserLeave = function(app, session) { if(!session || !session.uid) { return; } app.rpc.chat.chatRemote.kick(session, session.uid, app.get(‘serverId’), session.get(‘rid’), null); };

session.on(‘closed’, onUserLeave.bind(null, self.app));

session是怎么传到onUserLeave里面去的呢?另外onUserLeave.bind的第一个参数为什么是null?


8 回复

当然可以!让我们来详细解析一下这段代码中的 bind 方法是如何工作的。

背景信息

在 Node.js 中,bind 是一个非常有用的函数,它允许你预先设置一个函数的上下文(即 this 的值)以及一些预设参数。这在处理事件处理器、回调函数等场景时特别有用。

示例代码分析

var onUserLeave = function(app, session) {
    if (!session || !session.uid) {
        return;
    }
    app.rpc.chat.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
};

session.on('closed', onUserLeave.bind(null, self.app));

解释

  1. onUserLeave 函数

    • 这是一个普通的 JavaScript 函数,接受两个参数:appsession
    • 在函数内部,首先检查 session 是否存在且包含 uid 属性。如果不存在,则直接返回。
    • 然后调用 app.rpc.chat.chatRemote.kick 方法,并传递 session 和其他参数。
  2. session.on('closed', ...)

    • 这行代码的意思是当 session 关闭时,触发 onUserLeave 函数。
    • 但是,这里使用了 bind 方法来修改 onUserLeave 函数的行为。
  3. onUserLeave.bind(null, self.app)

    • bind 方法用于创建一个新的函数,该函数在调用时会将 self.app 作为第一个参数传递给 onUserLeave
    • 第一个参数 null 表示新函数的 this 上下文为 null。在大多数情况下,我们可以忽略这一点,除非我们确实需要指定 this 的值。
    • 第二个参数 self.app 则会被传递给 onUserLeave 函数的第一个参数 app

示例代码执行过程

假设 self.app 是一个应用程序实例,那么当 session 关闭时:

  • onUserLeave.bind(null, self.app) 创建了一个新的函数,其行为类似于:
    function(app, session) {
        // app 参数被替换为 self.app
        var newApp = self.app;
        if (!session || !session.uid) {
            return;
        }
        newApp.rpc.chat.chatRemote.kick(session, session.uid, newApp.get('serverId'), session.get('rid'), null);
    };
    
  • session 触发 'closed' 事件时,这个新函数会被调用,self.app 作为 app 参数传递进去。

总结

bind 方法在这里的作用是确保在 session 关闭时,onUserLeave 函数能够正确地访问 self.app 实例。通过 bind,你可以预先设置函数的一些参数,从而简化回调函数的编写和调用。


还有个问题,为什么要bind?直接调用onUserLeave不行么?怎么感觉多此一举

依我愚见,此处的 bind 多此一举。

个人理解的: bind同样是对象冒充,只不过bind只不同于call和apply的是,bind返回的先是类似1个继承了Function.prototype的子类(函数) 内部的实现才是真正的类似Function.prototype.call的。自己封装加了注释

if ( !(Function.prototype.bind ) ) {
  Function.prototype.bind = function ( that ) {
  var args = Array.prototype.slice.call( arguments, 1 ); //获取调用bind方法的参数数组
  var _self = this; // 代表当前Function.prototype
  var funCaller = function () {
   return _self.call( that, args.concat( Array.prototype.slice( arguments ) ) ); //即使当前Function.prototype call调用
  }
  funCaller.prototype = _self.prototype; //bind调用后创建的函数继承与当前Function.prototype
  return funCaller; 
 }	

} function g () { console.log( this.name ); } g.prototype = { name: ‘看片’ } g.bind( { name: ‘下片’ } )();

ps: => 下片

pomelo的没用过,呵呵

function fn(){ console.log(this); }

var fn2 = fn.bind(document);

fn2.call(window);

你可以执行以下…

session.on(‘closed’, onUserLeave.bind(null, self.app));

其中 null 是 当该方法执行时的this 指针 ,self.app 是 该方法调用时默认传入的 第一个参数。

如下所示 : var person = { id: ‘001’, outPut :function(name,job) { console.log( “id :” + this.id + “name :” + name + " job" + job ); } } ;

person.outPut(‘li’,‘nodeJs developer’);

person.id = ‘002’; person.outPut.bind(person,‘liz’);

person.outPut(‘android developer’);

bind 方法是 JavaScript 中的一个内置方法,用于创建一个新的函数,并且当这个新函数被调用时,它会使用 bind 方法指定的 this 值以及预设的一些参数。

在你的例子中,onUserLeave 函数需要两个参数:appsession。但是当你将 onUserLeave 绑定到 session.on('closed', ...) 的时候,你想预先设置 app 参数的值,而让 session 参数在事件触发时自动传入。

  1. bind 方法的第一个参数:通常情况下,bind 的第一个参数是用来指定调用该函数时 this 的上下文(即函数内部的 this 指向的对象)。在这个例子中,由于 onUserLeave 并不直接依赖于 this,所以传递 null 表示不会改变 this 的值。

  2. 预设参数:如果你希望在调用 onUserLeave 时,某些参数已经被预先设定好,你可以通过 bind 方法来实现。在你的例子中,self.app 将作为 app 参数被预设,而 session 将在事件触发时自动传入。

示例代码解释:

// 定义一个函数 onUserLeave
var onUserLeave = function(app, session) {
    if (!session || !session.uid) {
        return;
    }
    // 使用 pre-set 的 app 参数
    app.rpc.chat.chatRemote.kick(session, session.uid, app.get('serverId'), session.get('rid'), null);
};

// 假设 self.app 已经被定义并初始化为应用程序实例
session.on('closed', onUserLeave.bind(null, self.app));

在这个例子中,onUserLeave.bind(null, self.app) 创建了一个新的函数,当 session 关闭时被调用。这个新函数内部的 app 参数已经被设置为 self.app,而 session 参数则会在事件触发时自动填充。

回到顶部