Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获得';这';参考第二级原型功能_Javascript_Prototype Programming_Prototypal Inheritance - Fatal编程技术网

Javascript 获得';这';参考第二级原型功能

Javascript 获得';这';参考第二级原型功能,javascript,prototype-programming,prototypal-inheritance,Javascript,Prototype Programming,Prototypal Inheritance,我相当肯定这是不可能的,但我想看看是否有人有一些巧妙的想法,如何使之成为可能 我希望以下代码能够正常工作: var x = new foo(); x.a.getThis() === x; // true 换句话说,我希望x.a.getThis在本例中引用this为x。有道理吗 要使其正常工作,一个深度级别很简单: function foo(){} foo.prototype.getThis = function(){ return this; } var x = new foo(); x.ge

我相当肯定这是不可能的,但我想看看是否有人有一些巧妙的想法,如何使之成为可能

我希望以下代码能够正常工作:

var x = new foo();
x.a.getThis() === x; // true
换句话说,我希望
x.a.getThis
在本例中引用
this
x
。有道理吗

要使其正常工作,一个深度级别很简单:

function foo(){}
foo.prototype.getThis = function(){ return this; }
var x = new foo();
x.getThis() === x; // true
有一件事,我想让它作为一个原型工作,通过手动绑定到
this
,没有“欺骗”:

function foo(){
    this.a = {
        getThis : (function(){ return this; }).bind(this)
    };
}
虽然上面是我试图实现的一个完美的函数示例,但我不希望每个实例都有额外的函数:)


仅供参考,这里的实际用例是,我正在创建类来表示节点中的Cassandra对象,我希望能够通过
foo.a.b
引用超级列-->列族-->列,并在deep函数中保留对
foo
的引用。

如果没有某种强制绑定,就无法做到这一点。你说你不想“作弊”,但这违反了关于这是什么的标准规则,所以你必须作弊。但是JS让你作弊,所以一切都很好

顺便说一句,为了它的价值,咖啡脚本使这变得如此琐碎

foo = ->
  @a = getThis: => this
胖箭头
=>
从调用它的作用域中保留此的上下文。这允许您轻松地将上下文转发到另一个级别

该代码被编译成以下JS:

var foo;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
foo = function() {
  return this.a = {
    getThis: __bind(function() {
      return this;
    }, this)
  };
};
这基本上只是做了你说你不想做的事


或者,如果该值不一定非得
,则可以在子对象中设置“所有者”

var A = function(owner) {
  this.owner = owner;
};
A.prototype.getThis = function() {
  return this.owner;
};
var Foo = function() {
  this.a = new A(this);
};

var foo = new Foo();

if (foo.a.getThis() === foo) {
    alert('Happy dance');
} else {
    window.location = 'https://commons.lbl.gov/download/attachments/73468687/sadpanda.png';
}

而咖啡剧本的版本,是因为我是一个充满激情和无理的狂热者:

class A
  constructor: (@owner) ->
  getThis: -> @owner

class Foo
  constructor: -> @a = new A(this)

foo = new Foo()
if foo.a.getThis() is foo
  alert 'Happy Dance'
else
  window.location = 'https://commons.lbl.gov/download/attachments/73468687/sadpanda.png'

如果不在开始时绑定值,则无法可靠地执行此操作,因为函数的this值是由调用设置的。您无法事先知道将如何调用它,或者哪些函数需要特殊或受限调用来“保留”this->this关系

函数或调用方的
this
可以是任何对象,可能根本没有this->this。考虑:

var x = {
  a : {
    b: function() {return this;}
  }
}
当你调用
x.a.b()
,那么b的
这个
就是a。但如果你这样做了:

var c = x.a.b;
c(); // *this* is the global object


在这种情况下,这个->这个有什么价值?

回答我自己的问题,因为其他人可能会发现它很有用。我不确定我最终会选择这个还是斯奎吉的解决方案。函数只定义一次,然后克隆包含的对象,并将
parent=this
注入其中:

function foo(){
    var self = this, nest = this.__nestedObjects__ || [];

    nest.forEach(function(prop){
        self[prop] = extend({ parent : self }, self[prop]);
    });
}

// bound like this so that they're immutable
Object.defineProperties(foo.prototype, {
    bar : {
        enumerable : true,
        value : {
            foobar : function(){
                return this.parent;
            },
            foo : function(){},
            bar : function(){}
        }
    },
    __nestedObjects__ : { value : ['bar'] }
});

var fooInst = new foo();
console.log(fooInst.bar.foobar() == fooInst);

或者基于Squeegy的解决方案:

function foo(){
    for(var cls in this.__inherit__){
        if(!this.__inherit__.hasOwnProperty(cls)){ continue; }

        this[cls] = new (this.__inherit__[cls])(this);
    }
}

var clsA;
// bound like this so that they're immutable
Object.defineProperties(foo.prototype, {
    __inherit__ : { value : {
        bar : clsA = function(parent){
                Object.defineProperty(this, '__parent__', { value : parent });
            }
        }
    }
});

clsA.prototype = {
    foobar : function(){
        return this.__parent__;
    }
};

var fooInst = new foo();
console.log(fooInst.bar.foobar() == fooInst);

你的意思是你想要
Function.prototype.getThis=Function(){}
?不,我想要
getThis
让它的
这个
引用指向2级以上的对象,在本例中是
x
。我将修改这个问题,希望能让它更清楚。
var that=this;this.a={getThis:function(){返回该}}不好?@alex-出于代码整洁和性能原因,我不想在构造函数中递归地重新定义一组函数。如果我这样做的话,我实际上会重新定义和包装一个好的70-100函数,从而在创建的类的每个实例上增加70-100个闭包。我试图找出如何在原型中保留函数引用的同时使其工作,这样我就不会创建成千上万的新函数。是的,我试图找出如何不包装每个函数,我想我刚刚做了:)现在写一个测试用例你想要的对象是
这个
还是通过闭包共享的其他局部变量很重要?它可以是任何东西,这是我刚刚意识到的(你的问题让我觉得我们可能有相同的解决方案,但我很好奇你在想什么),我只是不想包装每一个函数原型谢谢,这是一个非常直接的解决方案:)我刚刚发布了我自己的,仅供参考,不确定我会使用哪一个,但你的肯定很有帮助!你能把这个图片加到你的答案里吗?这将使它成为史诗:P
function foo(){
    for(var cls in this.__inherit__){
        if(!this.__inherit__.hasOwnProperty(cls)){ continue; }

        this[cls] = new (this.__inherit__[cls])(this);
    }
}

var clsA;
// bound like this so that they're immutable
Object.defineProperties(foo.prototype, {
    __inherit__ : { value : {
        bar : clsA = function(parent){
                Object.defineProperty(this, '__parent__', { value : parent });
            }
        }
    }
});

clsA.prototype = {
    foobar : function(){
        return this.__parent__;
    }
};

var fooInst = new foo();
console.log(fooInst.bar.foobar() == fooInst);