gpt4 book ai didi

javascript - 通过异步回调设置对象文字属性值。

转载 作者:行者123 更新时间:2023-11-29 17:30:39 25 4
gpt4 key购买 nike

我正在创建一个检测高级浏览器功能的自包含 javascript 实用程序对象。理想情况下,我的对象看起来像这样:

Support = {
borderRadius : false, // values returned by functions
gradient : false, // i am defining
dataURI : true
};

我当前的问题涉及我从 Weston Ruter's site 改编的一些代码它检测 dataURI 支持。它尝试使用 javascript 创建带有 dataURI 源的图像,并使用 onload/onerror 回调来检查宽度/高度。由于 onload 是异步的,我失去了我的范围并且返回 true/false 不会将 true/false 分配给我的对象。

这是我的尝试:

Support = {
...
dataURI : function(prop) {
prop = prop; // keeps in closure for callback
var data = new Image();
data.onload = data.onerror = function(){
if(this.width != 1 || this.height != 1) {
prop = false;
}
prop = true;
}
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
return -1;
}(this)
};

我立即执行匿名函数,传递它(我希望它是对 Support.dataURI 的引用),但不幸的是引用了窗口对象——因此值始终为 -1。在创建 Support 对象后,我可以通过使用外部定义的函数来分配值来让它工作……但我不认为那样很干净。有没有办法让它独立?对象字面量的函数可以引用分配给它的属性吗?

编辑 ----------------------------------
不完全是我的问题的答案(措辞)所以我不打算发布额外的答案,但是......我决定使用单例对象而不是对象文字。这是工作代码:

Support = new function Support() {
var that = this;
this.dataURI = function() {
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==";
return that.dataURI;
}();
};

最佳答案

Can the object literal's function reference the property it's assigned to?

是的,它可以。每个函数都有一个本地 arguments变量,它有一个引用被调用函数的 callee 属性。所以如果你想引用 Support.dataURI,你可以简单地使用它:

var Support = {
...
dataURI: function(prop)
{
// Do whatever here with arguments.callee
}
};

但是,我认为这并不是您真正想要的。看起来您正在尝试引用属性名称,而不是值——在这种情况下,您的答案是否定的。 JavaScript 方法无法知道它存储在哪些属性中;事实上,它可以同时存储在多个属性中。例如:

var Support = {
...
dataURI: function(prop)
{
}
};
Support.somethingElse = Support.dataURI;

这里,Support 有两个属性都指向同一个方法。但是,该方法本身无法知道调用了哪个引用。由于 Support 对象尚未声明,您无法引用它。

事实上(虽然你问“对象文字的函数是否[可以]引用它分配给的属性”),函数甚至没有存储在对象上:它的结果是。因此,该方法本身与 Support 没有任何关联。

恐怕你最好先声明对象,然后设置它的 dataURI 属性。


回应您的修改

首先,你不需要在“function”之前加上“new”关键字。不过,我看不出这在任何浏览器中如何工作。如果简化它,代码的第 3-14 行的形式为“this.dataURI = fn();”。以下是这样的语句的工作原理:

  1. 该值是通过执行fn()
  2. 确定的
  3. 值分配给 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==";

};

但请记住:仍然无法保证(至少我知道)onloadonerror 处理程序会在您设置源时同步(立即)触发——事实上,甚至可以保证他们不会!因此,您可能会向 Support 对象添加回调,并在设置 dataURI 后执行它。但是,您必须防止 onloadonerror 同步执行的可能性。这样的事情应该有效:

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

关于javascript - 通过异步回调设置对象文字属性值。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4522167/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com