什么对象中的JavaScript功能势必会(什么是它的“本”)?(What object javas

2019-07-18 04:10发布

我知道,在函数内部它是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()

编辑:

你不能真正称之为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);
}

和不改变对象部分应用程序,该功能被绑定到:

function partial(f) {
   return f.bind(f.boundto(), arguments.slice(1));
}

共识:

你不能做到这一点。 概述:使用bindthis非常小心:)

Answer 1:

部分应用程序

你可以做局部的应用:

// 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)));
    };

}

这个函数必将什么对象?

此外,有一个非常直接的解决你的问题的第一部分。 不知道这是一个选择,但你可以在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;
    }
});

只要运行任何其它脚本得到运行之前,以及使用任何脚本bind ,它会自动添加一个boundObject属性的功能:

function f() { }
var o = { };
var g = f.bind(o);
g.boundObject === o; // true

(注:我假设你在ES5环境是上面由于您使用的事实bind )。



Answer 2:

在JavaScript功能在技术上并不必然要什么。 它可以声明为一个对象作为一个属性:

var obj = {
    fn: function() {}
}
obj.fn();

但是,如果你本身得到的功能到它自己的变量,它不绑定到任何特定的对象。

例如,如果你这样做:

var obj = {
    fn: function() {}
}
var func = obj.fn;
func();

然后,当你调用func()这反过来执行fn()函数,它将有没有关联obj都当它被调用。 关联与功能的对象由函数的调用来完成。 它不是功能的属性。

如果一个人使用fn.bind(obj)创建一个新的功能,只是在内部执行调用obj.fn() 它不会奇迹般地增加任何新功能的JavaScript。 事实上,你可以看到一个填充工具.bind()看看它是如何工作在这里MDN 。


如果你期待this永远是一个特定对象,无论功能如何被调用,这不是多么JavaScript的工作。 除非将函数实际上是强制使用硬wird对象(有什么关联时,它被称为垫片.bind()一样),那么功能不具有硬连线的关联。 该协会是由主叫方基于它是如何调用该函数来完成。 这比一些其他语言不同。 例如,在C ++中,你不能调用一个函数,而不正确的对象在通话时间与它相关联。 语言根本不会解决函数调用,你会得到一个编译错误。

如果您在类型在JavaScript中的分支,那么你可能不会使用语言的面向对象的功能正常,或者给你最好的优势。



Answer 3:

取而代之的是功能结合func的对象,为什么不尝试治疗func为对象,可容纳OBJ1和OBJ2,作为其属性?

例如:

var func = function {
    this.object; // Could be obj1 or obj2
    return this.f === arguments.callee;
    // => true, if this.object is not null
}

var f = func;

f.object = obj1; // or func.object = obj2;

您也可以编写处理该物体是否为OBJ1或OBJ2的功能:

function g(f) {
  if (typeof(f) !== 'function') throw 'error: f should be function';

  if (f.object === obj)
    // this code will run if g(f) was called
    doSomething(f);
  if (f.object === obj2)
    // this code will run if g(f) or g(bound) was called
    doSomethingElse(f);
}

原因是,你要正确对待OBJ1和OBJ2作为函数的性质f 。 但是,当您绑定,您要添加的功能或者OBJ1或OBJ2的属性。 这是可能的绑定功能,以多个对象,所以它没有任何意义,寻找到你绑定的功能一个对象; 因为你要添加的功能为对象的一个​​子集。

在这种情况下,由于要处理的对象作为函数的一个子集,它可能是有意义的属性添加到可以容纳OBJ1或OBJ2的功能。



Answer 4:

如果你是一个做了绑定,您可以将字段添加到功能来记录这为以后的测试。

var that = "hello";
var xyz = function () { console.log(this); }.bind(that);
xyz.that = that;

// xyz is callable as in xyz(), plus you can test xyz.that without calling


文章来源: What object javascript function is bound to (what is its “this”)?