作为对象属性访问Jquery选择器,结果出乎意料

7
假设我有一个长这样的
<div id="testDiv">some stuff in here</div>

我有一个定义对象字面量的脚本:
var testObject = 
{
    testDiv: $("#testDiv"),
    testDivProperty: this.testDiv    
};

为什么当我访问 testObject.testDiv 时,会得到一个 jQuery 对象的引用,即:
[<div id=​"testDiv">​…​</div>​]

但是当我访问 testObject.testDivProperty 时,我得到的是对实际元素的引用,即:
<div id=​"testDiv">​…​</div>​

因此,我无法对 testObject.testDivProperty 执行 jQuery 操作吗?

可以对它执行jQuery操作,但这意味着再次包装它- $(testObject.testDivProperty);。不过我只是评论而已。我和你一样好奇 :) - Reinstate Monica Cellio
就我个人而言,在 Chrome 上查询 testObject.testDivProperty 时,会得到 undefined(使用 body 而不是 #testDiv 进行测试)。 - h2ooooooo
1
我刚在Chrome中使用上述代码进行了测试,并得到了与OP相同的结果。 - Reinstate Monica Cellio
这是预期的结果,但我不太确定为什么jQuery元素被取消包装?-> http://jsfiddle.net/CQw5v/ - adeneo
1
this 是窗口对象,而 this.testDiv 引用原生 DOM 元素,因为在某些浏览器中它附加到窗口上。 - adeneo
显示剩余5条评论
6个回答

3
尝试在对象实例化期间引用正在定义的对象作为“this”,结果并不像您期望的那样工作。
在您的示例中,“this”实际上指的是“window”对象。某些浏览器(例如Chrome和IE)将命名的DOM节点附加到“document”和/或“window”对象上,这就是为什么“this.testDiv”引用具有“id =“testDiv””的元素的原因。巧合的是,您尝试访问的属性名称具有与元素ID相同的值。
为了演示实际发生的情况,请尝试以下操作:
<div id="test"></div>

var myObj = {
    prop1: $('#test'),
    prop2: this.prop1
};

myObj的上下文中,this.prop1应该是undefined,但是window.test(取决于浏览器)可能指代DOM节点<div id="test"></div>。根据你的示例,你可以按照以下方式完成你的任务:
var myObj = { prop1: $('#test') };
myObj.prop2 = myObj.prop1;

或者

var test = $('#test');
var myObj = {
    prop1: test,
    prop2: test
};

1

这样做是不行的。this在这个上下文中指的是window

var testObject = 
{
    testDiv: $("#testDiv"),
    testDivProperty: this.testDiv // window.testDiv

}

1
但是为什么testDiv作为window的属性存在,并且为什么它引用了正确的DOM节点?这是文档化的行为吗? - André Dion
4
在某些浏览器中,元素通过名称或ID与窗口相关联,这就是为什么 window.testDiv 能够工作的原因,它是元素的ID。 - adeneo
2
https://dev59.com/-3A75IYBdhLWcg3wK1wp - adeneo
1
它还在草稿阶段,可能会被标准化,但我认为Firefox根本不支持这个功能,而且在窗口对象中混杂所有具有非空属性的活动文档中任何HTML元素的id和/或name属性值是一种非常糟糕的做法。 - adeneo
这些是几个月前发布的规范建议吗? - adeneo
显示剩余15条评论

0
如前所述,this 指的是全局窗口对象。
之所以 this.testDiv 指向 DOM 元素,是因为 Web 浏览器中存在一种标准行为,即为每个具有 ID 的 DOM 元素添加全局引用。这些引用是在解析元素时添加的,因此您的脚本代码必须位于元素下方才能引用它们。
是否依赖这些引用是另一个讨论话题。

0

实际上,在第一种情况下,获取jQuery对象是显而易见的,并且应该被理解(因为您使用了'$')。在第二种情况下,由于以下原因,您会得到对简单的DOM节点(对象)的引用 -

- 您没有在其中任何地方使用jQuery,因此不要期望它是一个jQuery对象。

- 您访问了this.testDiv,这意味着 - 给我当前节点(正在访问的节点)的名为“testDiv”的属性。现在,如果您在<body>标记中编写了此代码,则this应该指向body元素的节点/对象(在DOM中)。我不确定这部分,但是,某种方式上,您的'testDiv'对象已在body对象中注册为属性(可能是因为您为此元素使用了“id”属性,从而使其唯一)。因此,当您尝试使用this.testDiv获取对象时,您将获得DOM中<div>元素的确切对象。默认情况下,JavaScript会为您提供对DOM / JavaScript对象的简单引用(而不是jQuery对象)。

除此之外,jQuery对象可以被视为普通JavaScript/DOM对象的一种包装。虽然这不是问题的一部分,但如果您仍然想要作为jQuery对象访问,则可以执行以下操作将JavaScript对象Obj转换为jQuery对象:Obj=$(Obj);新的Obj将成为一个jQuery对象。

不,当脚本被包含在<body>元素中时,this不会指向该元素。你为什么会这样想呢? - Bergi

0

经过一些尝试,我找到了答案。在创建第二个属性的时候,this指的是window,在那里你有一个id为testDiv的div。

所以你实际上正在做这件事...

var testObject = 
{
    testDiv: $("#testDiv"),
    testDivProperty: window.testDiv    
}

个人不知道你可以这样做,但是window.testDiv会返回具有ID testDiv的DOM元素。


0
let object = $('#someId') -- jQueryObject

accesing any custom object field

object[0].anyProp = 'anyValue'

console.log(object) -- jQuery object
console.log(object[0]) -- Raw JS object
console.log(object[0].anyProp) -- Raw JS object prop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接