有没有可能保护'this'引用绑定对象内的函数
Is it possible to protect the 'this' reference binding a function within an object?
给出以下JavaScript(相关的HTML将在问题的底部发布):
var app = {
// other objects from 'messages' array removed for brevity
'messages': [{
'author': 'Maya Angelou',
'quote': "If you don't like something, change it. If you can't change it, change your attitude."
}],
'textProp': 'textContent' in document.body ? 'textContent' : 'innerText',
'outputTo': document.querySelector('#output'),
'trigger': document.querySelector('#load'),
'quote': function () {
var n = Math.floor(Math.random() * this.messages.length),
f = document.createElement('figure'),
c = document.createElement('figcaption'),
frag = document.createDocumentFragment();
f[this.textProp] = this.messages[n].quote;
c[this.textProp] = this.messages[n].author;
frag.appendChild(f);
frag.appendChild(c);
this.outputTo.innerHTML = '';
this.outputTo.appendChild(frag);
}
};
可以从对象外部调用quote()
函数,使用如下命令:
document.getElementById('load').addEventListener('click', app.quote.bind(app));
JS Fiddle demo.
或者直接调用函数(不作为回调绑定到事件处理程序):
app.quote();
JS Fiddle demo.
然而,我尝试在对象本身中创建一个事件处理程序,使用:
'clickhandler': function(){
this.trigger.addEventListener('click', this.quote);
}
JS Fiddle demo.
当然,这失败了(正如预期的那样,因为这里的this
是(使用IIFE) Window
对象)。
我意识到this
将,而对象正在创建/在其初始化之前,引用Window
对象,但是是否有一种方法我没有看到创建和触发对象本身内的事件处理?
我意识到我想象中的互联网点的很大一部分来自JavaScript,但是学习它意外地导致了完全的困惑和不足的时刻;这不是在原谅我的无知,而是在解释我的无知。
最后,HTML(如它是):
<button id="load">Switch message</button>
<div id="output"></div>
顺便说一下,我看了以下链接/建议的问题:
为了清楚起见,我试图创建对象本身,并在对象中完全创建和分配事件处理,而不必在之后调用其方法。这就是我被困住的地方(我怀疑这可能是不可能的)。
- 是否可以在同一对象内引用对象?-我没有看到相关性(尽管也许我只是在这一点上累了)。
- 是否有可能从子对象的函数内隐式引用父对象的成员?-这表明唯一可能的方法是通过添加一个新方法来扩展
app
对象的初始化,这是可行的,但确实违背了我想要做的事情(我意识到生活是不公平的,但即使如此…)。Javascript在对象中使用绑定,我如何访问对象this?-处理事件处理程序,但似乎不直接适用。不过我可能是误解了。
正如您所指定的,如果您只想创建一个新对象,您可能需要这样做。我认为无论你做什么,你仍然需要执行一些东西-无论是实例化一个对象还是运行绑定点击的特定init函数。
var App = function App(){
this.clickhandler()
}
App.prototype =
{
'messages': [{
'author': 'Maya Angelou',
'quote': "If you don't like something, change it. If you can't change it, change your attitude."
}, {
'author': 'Richard Feynman',
'quote': "Hell, if I could explain it to the average person, it wouldn't have been worth the Nobel prize."
}, {
'author': 'Eddie Izzard',
'quote': "Cats have a scam going – you buy the food, they eat the food, they fuck off; that's the deal."
}, {
'author': 'George Carlin',
'quote': "I would never want to be a member of a group whose symbol was a man nailed to two pieces of wood. Especially if it's me!"
}],
'textProp': 'textContent' in document.body ? 'textContent' : 'innerText',
'outputTo': document.querySelector('#output'),
'trigger': document.querySelector('#load'),
'quote': function () {
console.log('hey')
var n = Math.floor(Math.random() * this.messages.length),
f = document.createElement('figure'),
c = document.createElement('figcaption'),
frag = document.createDocumentFragment();
f[this.textProp] = this.messages[n].quote;
c[this.textProp] = this.messages[n].author;
frag.appendChild(f);
frag.appendChild(c);
this.outputTo.innerHTML = '';
this.outputTo.appendChild(frag);
},
'clickhandler' : function(){
this.trigger.addEventListener('click', this.quote.bind(this));
}
};
//just create an object
app = new App();
http://jsfiddle.net/LwrvT/在某些时候,您将需要将.bind()
方法替换为app
(除非您避免使用this
并将其替换为app
)。然而,这并不一定在传递 app.quote
方法的地方(例如,将绑定作为事件侦听器),但可以直接在app
对象声明之后:
var app = {
…,
quote: function() {
… this …
}
};
app.quote = app.quote.bind(app);
如果周围有下划线,可以使用bindAll
辅助函数:
var app = _.bindAll({
…,
quote: function() {
… this …
}
}, "quote");
如果你不在对象文本中——它可以是构造函数,IEFE,等等——你可以直接在它的声明位置.bind()
函数:
function App() {
…
this.quote = function() {
… this …
}.bind(this);
}
对于coffeescript或ES6,您还可以使用fat-arrow函数语法作为糖。
除了对象文字,您还可以这样做:
var app = new function () {
this.messages = [{
'author': 'Maya Angelou',
'quote': "If you don't like something, change it. If you can't change it, change your attitude."
}, {
'author': 'Richard Feynman',
'quote': "Hell, if I could explain it to the average person, it wouldn't have been worth the Nobel prize."
}, {
'author': 'Eddie Izzard',
'quote': "Cats have a scam going – you buy the food, they eat the food, they fuck off; that's the deal."
}, {
'author': 'George Carlin',
'quote': "I would never want to be a member of a group whose symbol was a man nailed to two pieces of wood. Especially if it's me!"
}];
this.textProp = 'textContent' in document.body ? 'textContent' : 'innerText';
this.outputTo = document.querySelector('#output');
this.trigger = document.querySelector('#load');
this.quote = function () {
var n = Math.floor(Math.random() * this.messages.length),
f = document.createElement('figure'),
c = document.createElement('figcaption'),
frag = document.createDocumentFragment();
f[this.textProp] = this.messages[n].quote;
c[this.textProp] = this.messages[n].author;
frag.appendChild(f);
frag.appendChild(c);
this.outputTo.innerHTML = '';
this.outputTo.appendChild(frag);
};
this.trigger.addEventListener('click', this.quote.bind(this));
};
查看工作演示
这个变量只是引用app,所以就用app。
var app = {
someVar: 'thing',
someMethod: function(){
alert(app.someVar);
}
};
或者
function createApp(){
var app = {};
app.someVar = 'thing';
app.someMethod = function(){
alert(app.someVar);
};
return app;
}
小改动。在初始化对象的属性之前声明对象可能会对您的用例有所帮助。
var app = {};
app["messages"] = "test message";
app["textProp'] = 'textContent' in document.body ? 'textContent' : 'innerText';
app['quote']= function () {
var n = Math.floor(Math.random() * this.messages.length),
f = document.createElement('figure'),
c = document.createElement('figcaption'),
frag = document.createDocumentFragment();
f[app.textProp] = app.messages[n].quote;
}
- 创建对象函数原型和代码是错误的
- JavaScript模块模式-如何在使用对象/函数之前激发构造函数/init函数
- 如何从onclick字符串中引用javascript对象函数
- 更改对象函数仅用于示例
- javascript和jQuery的嵌套对象函数中的变量范围
- 将对象函数传递给请求动画帧时丢失对象引用
- 对象函数返回函数而不是值
- 使用onclick调用属性对象函数
- javascript拉斐尔对象函数传递
- 如何从onClick事件调用对象函数
- 可以't获取具有“t”的对象变量;这个“;由setTimeout()函数调用的对象函数中的属性
- 对象没有't继承父对象函数
- 调用父对象函数
- "这个“;对象函数内部的引用
- 将变量添加到对象函数调用的末尾
- 传单错误:对象函数没有方法'createIcon'在LayerGroup中创建自定义图标标记时
- TypeError:对象函数Object(){〔本机代码〕}没有方法'方法'
- 挖空 - 单击绑定到对象函数 - 范围问题
- 类型错误: 对象函数...没有方法“打开”
- JavaScript 对象函数