我很想知道为什么jQuery版本'1.11.2'和'3.1.1'在jQuery对象中使用nodeType()函数时以两种不同的方式运行。
为了说明这一点,我为这两个版本提供了两个小提琴链接。
的jquery-1.11.2
https://jsfiddle.net/38z9m9j9/9/
的jquery-3.1.1
https://jsfiddle.net/38z9m9j9/8/
在这方面,我的条件是,
this.options.data == data.colors[0];
对于对象'this.options.data.colors [0]'使用' nodeType()'函数,仅在版本'1.11.2'中相同,其中不在'3.1中工作2.1' 。那么,'nodeType()'在'1.11.2'中是如何工作的?
提前致谢。
答案 0 :(得分:4)
这两个版本的jQuery中函数isPlainObject
的实现差异导致问题的原因。
当前isPlainObject在1.4测试.nodeType中因为IE使dom节点看起来像对象。这有$ .isPlainObject({nodeType:...})的副作用;当它应该返回true时将返回false。 (来自jQuery Forum)
使用jQuery 1.11.2
var data = {
colors: {
id: 1,
color: "red",
nodeType: function () {},
}
};
function logPlain (value, log) {
value && value.color == "red" && $('#plain').text(log);
}
//from release of jQuery UI-1.12.1
$.widget.extend = function( target ) {
var widgetSlice = Array.prototype.slice;
var input = widgetSlice.call( arguments, 1 );
var inputIndex = 0;
var inputLength = input.length;
var key;
var value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
logPlain(value, 'true');
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
logPlain(value, 'false');
target[ key ] = value;
}
}
}
}
return target;
};
$(function() {
$.widget("custom.widget2", {
options: {
data: null
},
_create: function() {
var isDataEqual = this.options.data == data.colors;
$('#equal').text(isDataEqual ? "true" : "false");
},
});
$("#my-widget1").widget2({
data: data.colors
});
});
#equal, #plain {
background-color: rgba(0, 128, 0, 0.31);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div>
<div id="my-widget1">Testing 'nodeType' in jQuery version-1.11.2</div>
<div>isPlainObject: <span id="plain"></div>
<div>isDataEqual: <span id="equal"></span></div>
</div>
使用jQuery 3.1.1:
var data = {
colors: {
id: 1,
color: "red",
nodeType: function () {},
}
};
function logPlain (value, log) {
value && value.color == "red" && $('#plain').text(log);
}
//from release of jQuery UI-1.12.1
$.widget.extend = function( target ) {
var widgetSlice = Array.prototype.slice;
var input = widgetSlice.call( arguments, 1 );
var inputIndex = 0;
var inputLength = input.length;
var key;
var value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
logPlain(value, 'true');
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
logPlain(value, 'false');
target[ key ] = value;
}
}
}
}
return target;
};
$(function() {
$.widget("custom.widget2", {
options: {
data: null
},
_create: function() {
var isDataEqual = this.options.data == data.colors;
$('#equal').text(isDataEqual ? "true" : "false");
},
});
$("#my-widget1").widget2({
data: data.colors
});
});
#equal, #plain {
background-color: rgba(0, 128, 0, 0.31);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div>
<div id="my-widget1">Testing 'nodeType' in jQuery version-3.1.1</div>
<div>isPlainObject: <span id="plain"></div>
<div>isDataEqual: <span id="equal"></span></div>
</div>
在创建新的jQuery UI小部件时调用堆栈:
如果$.isPlainObject(options.colors) == true
则将options.colors
克隆到新对象options
(jQuery 3.1.1)中。 isDataEqual
将是假的。
否则options.colors
通过引用复制到新对象options
(jQuery 1.11.0)。 isDataEqual
将是真的。
为什么呢?在方法$.isPlainObject
中的jQuery 1.11.2中,有以下检查:
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
因此,如果对象中存在属性nodeType
,方法$.isPlainObject
将返回false
。
答案 1 :(得分:0)