最近两天,我试图了解我的代码中的一个问题。
代码在这里: http://jsfiddle.net/a7wkpngr/
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
$.ajax({
url: '/',
data: $.extend({}, "")
})
如果您尝试运行此代码,则可以看到
TypeError: undefined is not a function // of course, coz this === window
我试图找到"为什么"。我发现,那个:
$.extend
中(如果第二个参数是对象,则没有例外)。$.extend
的情况下运行$.ajax
,一切正常
所以,问题是 - String.capitalize()
的运行方式和原因。
P.S。我知道,我知道,扩展本地类是非常糟糕的。
答案 0 :(得分:2)
通过调试代码,您可以看到,在使用带空选项的扩展时,它将在jquery源代码(版本2.0.1)中转到第201行。
如果你在这里放置断点,那么调用ajax扩展时。参数长度为2.一个是{},另一个是#34;"。
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
在这里循环使用属性(选项中的名称),迭代String的属性,所以实际上它应该添加所有字符串属性,但它只添加你添加的大写函数并将其返回到ajax参数。第一个for循环只执行一次,因为如果长度2和内部只运行一次,即在大写方法上。
现在检查以下输出:
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
String.prototype.capitalize2 = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
String.prototype.trim = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
Object.defineProperty(String.prototype, 'test',
{
value: function(){ return "test" },
enumerable: false
});
Object.defineProperty(String.prototype, 'test2',
{
value: function(){ return "test" },
enumerable: true
});
for (var key in "") {
console.log(key);
}
控制台输出:
大写
的 capitalize2 强>
test2
这导致你只是通过可枚举的属性进行迭代。
在此检查jsfiddle:http://jsfiddle.net/w9kdp96a/1/
来自mozilla:
for..in语句遍历一个的可枚举属性 对象,以任意顺序。对于每个不同的属性,语句都可以 被执行。
因此,如果您将大写方法定义为
Object.defineProperty(String.prototype, 'capitalize',
{
value: function(){ return this.charAt(0).toUpperCase() + this.slice(1); },
enumerable: false
});
它不会在ajax数据中。
答案 1 :(得分:1)
一些事情:
toUpperCase()
是JavaScript。例如,请参阅here。console.log('hello'.capitalize());
$.ajax({ url: '/', data: $.extend({}, {"hello":"world"}) })
将导致data: {"hello","world"}
作为$.ajax()
来电的一部分。
错误是由$ .extend()的第二个参数引起的,它是一个字符串,而不是一个对象。
答案 2 :(得分:1)
在评论中回答您的问题:only question is how and why String.capitalize runs,
如果你看到jquery source它将获取每个数据键(foreach(数据中的东西))并尝试用它创建一个查询字符串。
如果它是一个函数,它将调用它(注释来自jquery源代码):
var prefix,
s = [],
add = function( key, value ) {
// If value is a function, invoke it and return its value
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
};
SSA的答案可能是一个解决方案,但Object.defineProperty仅适用于IE9 and up。