esp*_*esp 19 javascript functional-programming function this ecmascript-5
我知道它在函数内部this.
var func = function {
return this.f === arguments.callee;
// => true, if bound to some object
// => false, if is bound to null, because this.f === undefined
}
var f = func; // not bound to anything;
var obj = {};
obj1.f = func; // bound to obj1 if called as obj1.f(), but not bound if called as func()
var bound = f.bind(obj2) // bound to obj2 if called as obj2.f() or as bound()
Run Code Online (Sandbox Code Playgroud)
你实际上不能打电话,obj2.f()因为f它不会成为你的财产obj2
问题是:如何找到函数绑定的对象,在这个函数之外?
我想实现这个目标:
function g(f) {
if (typeof(f) !== 'function') throw 'error: f should be function';
if (f.boundto() === obj)
// this code will run if g(obj1.f) was called
doSomething(f);
// ....
if (f.boundto() === obj2)
// this code will run if g(obj2.f) or g(bound) was called
doSomethingElse(f);
}
Run Code Online (Sandbox Code Playgroud)
和部分应用程序而不更改函数绑定的对象:
function partial(f) {
return f.bind(f.boundto(), arguments.slice(1));
}
Run Code Online (Sandbox Code Playgroud)
你不能这样做.外卖:使用bind并this非常小心:)
Nat*_*all 11
你可以做部分申请:
// This lets us call the slice method as a function
// on an array-like object.
var slice = Function.prototype.call.bind(Array.prototype.slice);
function partial(f/*, ...args */) {
if (typeof f != 'function')
throw new TypeError('Function expected');
var args = slice(arguments, 1);
return function(/* ...moreArgs */) {
return f.apply(this, args.concat(slice(arguments)));
};
}
Run Code Online (Sandbox Code Playgroud)
此外,对于问题的第一部分,还有一个非常直接的解决方案.不确定这是否适合您,但您可以很容易地在JS中修补问题.猴子修补bind是完全可能的.
var _bind = Function.prototype.apply.bind(Function.prototype.bind);
Object.defineProperty(Function.prototype, 'bind', {
value: function(obj) {
var boundFunction = _bind(this, arguments);
boundFunction.boundObject = obj;
return boundFunction;
}
});
Run Code Online (Sandbox Code Playgroud)
只需在任何其他脚本运行之前运行它,以及任何使用的脚本bind,它将自动boundObject向该函数添加一个属性:
function f() { }
var o = { };
var g = f.bind(o);
g.boundObject === o; // true
Run Code Online (Sandbox Code Playgroud)
(注意:由于您正在使用,我假设您处于ES5环境中bind.)
javascript 中的函数在技术上不受任何约束。它可以声明为对象的属性,如下所示:
var obj = {
fn: function() {}
}
obj.fn();
Run Code Online (Sandbox Code Playgroud)
但是,如果您将函数单独放入它自己的变量中,则它不会绑定到任何特定对象。
例如,如果你这样做:
var obj = {
fn: function() {}
}
var func = obj.fn;
func();
Run Code Online (Sandbox Code Playgroud)
然后,当您调用func()which 依次执行该fn()函数时,它与obj被调用时完全没有关联。将对象与函数关联是由函数的调用者完成的。它不是函数的属性。
如果要使用fn.bind(obj),则会创建一个新函数,该函数仅在内部执行对 的调用obj.fn()。它不会神奇地为 javascript 添加任何新功能。事实上,你可以在 MDN 上看到一个 polyfill.bind()来了解它是如何工作的。
如果您希望this无论函数如何调用都始终是一个特定的对象,那么 javascript 就不是这样工作的。除非一个函数实际上是一个 shim,它在被调用时强制与一个硬.bind()连线对象关联(是什么),那么一个函数没有一个硬连线关联。关联是由调用者根据调用函数的方式完成的。这与其他一些语言不同。例如,在 C++ 中,如果在调用时没有与之关联的正确对象,则无法调用函数。该语言根本无法解析函数调用,并且您会收到编译错误。
如果您在 javascript 中对类型进行分支,那么您可能没有正确使用该语言的面向对象功能或未发挥最大优势。
| 归档时间: |
|
| 查看次数: |
9098 次 |
| 最近记录: |