鉴于以下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));
或者直接调用函数(不绑定为事件处理程序的回调):
app.quote();
但是,我尝试在对象本身内创建一个事件处理程序,使用:
'clickhandler': function(){
this.trigger.addEventListener('click', this.quote);
}
这当然失败了(正如预期的那样,因为这里的this
是(使用IIFE)this Window
object)。
我意识到this
将在创建对象时/在初始化之前引用Window
对象,但有一种方法我没有看到创建,并触发对象本身内的事件处理?
我意识到我想象中的互联网点很大一部分来自JavaScript,但是学习它会意外地导致完全混乱和不足的时刻;这不是为了原谅我的无知,而是为了解释它。
最后,HTML(例如它):
<button id="load">Switch message</button>
<div id="output"></div>
顺便说一句,我已经查看了以下链接/建议的问题:
为了清楚起见,我尝试创建对象本身并创建事件处理并完全分配在&#39;中。对象,之后不必调用它的方法。这就是我被困的部分(我怀疑这可能是不可能的)。
app
对象,这是可行的,但确实违背了我< em>想去做(我意识到生活不公平,但即便如此......)。答案 0 :(得分:1)
正如您所指定的,如果您只是想创建一个新对象,您可能需要这样做。我认为无论你做什么,你仍然需要执行一些东西 - 无论是实例化一个对象还是运行一个绑定点击的特定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();
答案 1 :(得分:1)
在某些时候,您需要.bind()
方法app
(除非您avoid the use of this
and replace it with app
无处不在)。但是,这不一定在传递 app.quote
方法的地方(例如,绑定为事件侦听器),但可能直接在app
对象的声明之后:
var app = {
…,
quote: function() {
… this …
}
};
app.quote = app.quote.bind(app);
如果您有Underscore,可以使用bindAll
helper function:
var app = _.bindAll({
…,
quote: function() {
… this …
}
}, "quote");
如果你是not in an object literal - 它可能是一个构造函数,IEFE,无论如何 - 你可以.bind()
函数直接在它的声明位置:
function App() {
…
this.quote = function() {
… this …
}.bind(this);
}
使用coffeescript或ES6,你也可以使用fat-arrow函数语法作为糖。
答案 2 :(得分:1)
您可以执行以下操作,而不是对象文字:
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));
};
<强> SEE THE WORKING DEMO. 强>
答案 3 :(得分:0)
这个变量只是引用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;
}
答案 4 :(得分:0)
一个小小的变化。在初始化其属性之前声明对象可能有助于您的使用。
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;
}