错误的绑定技术?

时间:2015-06-06 11:17:41

标签: javascript

你有没有想过bind究竟做了什么以及bind是否可以被滥用?

这是被视为不良行为的对象模型(示例A)

var A = function() {
    this.foo = "foo";
    this.bar = function () {
        console.log("bar");
    };
};

这是相同的对象写得更好:

var A = function() {
    this.foo = "foo";
};

A.prototype.bar = function () {
    console.log("bar");
};

bar的每个实例都没有反复声明函数A。现在看下面的代码片段:

function origin() {
    console.log(this.toString() + " is who I am");
};

var listOfBindedF = [];

var dummyObject = {};

for(var i = 0; i<100;i++) {
    listOfBindedF.push(origin.bind(dummyObject));
}

对于每个绑定用法,我声明新功能不是吗?许多lib,框架和引擎在其核心中使用bind。不只是异步调用,没有绑定真的很难,但几乎无处不在,自定义继承就是很好的例子。

我做了一个简短的测试,我自己检查一下。

  • 长度为100k且充满origin个引用的数组 〜465KB。
  • 长度为200k的数组,100k引用origin和100k 引用dummyObject吃~1.1MB。
  • 长度为100k的数组 origin.bind(dummyObject)吃掉~9.5MB。

对于我们使用这些框架/库进行的javascript应用程序,是否存在bind性能影响?影响是否显着?它是否与示例A 相似?

1 个答案:

答案 0 :(得分:2)

首先,这是一个函数声明

function foo() {
}

这是一个函数表达式

var foo = function() {};

你的两个A是不同的。想象一下以下代码:

function A(foo) {
  this.bar = function() {
               console.log(foo);
             };
}

这会使foo保持私有状态,并且仍允许bar访问它,这是原型版A无法实现的。

至于内存问题:显然,每个function对象占用一些内存。函数表达式始终创建新对象。创建100个A实例将使用您的第一个示例创建分配给bar的100个函数对象。

函数声明在输入其周围范围时创建实例。因此,在这种情况下,100个A实例仍会创建100个bar实例:

function A(foo) {
  function bar() {
    console.log(foo); 
  }
  this.bar = bar;
}

bind还会创建一个需要更多内存的新函数对象(它必须存储对原始函数的引用,this的值等。)

使用bind会产生影响,但我怀疑这会导致您的应用出现性能问题。 FWIW:在bar的第一个示例中调用A比在第二个示例中调用它更快,因为没有必要上升原型链。

请注意,bind也可以用于currying,使其成为一个多功能的工具:

function log(message) {
  console.log(message);
}

var logHello = log.bind(null, 'Hello');
logHello(); // prints 'Hello' to the console

结论:使用最适合任务的工具。