Может ли функция литерала объекта ссылаться на свойство, которому оно назначено?
Да, может.Каждая функция имеет локальную переменную arguments , которая имеет свойство callee
, которое ссылается на вызываемую функцию.Поэтому, если вы хотите сослаться на Support.dataURI, вы можете просто использовать это:
var Support = {
...
dataURI: function(prop)
{
// Do whatever here with arguments.callee
}
};
Однако я не думаю, что это действительно то, что вы хотите.Похоже, вы пытаетесь сослаться на свойство name , а не на значение - в этом случае ваш ответ - нет.У метода JavaScript нет возможности узнать, в каких свойствах он хранится;действительно, он может храниться в нескольких свойствах одновременно.Например:
var Support = {
...
dataURI: function(prop)
{
}
};
Support.somethingElse = Support.dataURI;
Здесь Support
имеет два свойства, которые оба указывают на один и тот же метод.Однако сам метод не может знать, какая ссылка была вызвана.А поскольку объект Support
еще не объявлен, вы не можете ссылаться на него.
На самом деле (хотя вы спрашиваете, ссылается ли «функция литерала объекта на свойство, которому она назначена»)функция даже не сохраняется в объекте: ее результатТак что сам метод никак не связан с Support
.
Боюсь, вы можете объявить объект как можно лучше, а затем установить его свойство dataURI
.
В ответ на ваше изменение
Прежде всего, вам не нужно ключевое слово "new" перед "функцией".Тем не менее, я не вижу, как это может работать в любом браузере.Если вы упростите его, строки 3–14 вашего кода будут иметь вид «this.dataURI = fn ();».Вот как работает такой оператор:
- Значение определяется путем выполнения
fn()
- Значение присваивается свойству
dataURI
.
В момент выполнения fn()
, dataURI
еще не был назначен, поэтому нет способа получить доступ к его (правильному) значению, чтобы вернуть его.
Кроме того, у вас есть(по крайней мере, потенциально) асинхронный процесс (ожидание загрузки изображения или ошибки), поэтому значение не будет даже установлено обратным вызовом.По сути, вы пытаетесь обернуть асинхронный процесс (onload
событие) в синхронный (вызов функции).
Наконец, вам не нужно создавать и выполнять функцию здесь.Просто избавьтесь от этого:
var Support = function() {
var that = this;
var data = new Image();
data.onload = data.onerror = function(){
if(this.width != 1 || this.height != 1) {
that.dataURI = false;
} else {
that.dataURI = true;
}
}
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
};
Но помните: все еще нет гарантии (по крайней мере, я знаю), что обработчики onload
и onerror
будут запускаться синхронно (немедленно), когда вы устанавливаетеисточник - на самом деле, может даже быть гарантия, что они не будут!Таким образом, вы, вероятно, добавите обратный вызов к вашему Support
объекту и выполните его, как только будет установлен dataURI
.Тогда, однако, вам придется остерегаться того, что onload
или onerror
выполняется синхронно.Примерно так должно работать:
var Support = function() {
var that = this;
this.getDataURI = function()
{
var data = new Image();
data.onload = data.onerror = function(){
if(this.width != 1 || this.height != 1) {
that.dataURI = false;
} else {
that.dataURI = true;
}
if (that.onDataURI)
that.onDataURI();
}
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
}
};
var mySupport = new Support();
mySupport.onDataURI = function() { alert(mySupport.dataURI); }
mySupport.getDataURI();