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