你有没有想过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。不只是异步调用,没有绑定真的很难,但几乎无处不在,自定义继承就是很好的例子。
我做了一个简短的测试,我自己检查一下。
origin
个引用的数组
〜465KB。 origin
和100k
引用dummyObject
吃~1.1MB。 origin.bind(dummyObject)
吃掉~9.5MB。对于我们使用这些框架/库进行的javascript应用程序,是否存在bind
性能影响?影响是否显着?它是否与示例A 相似?
答案 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
结论:使用最适合任务的工具。