扩展JavaScript字符串和JQuery.ajax
最近两天,我试图理解代码中的一个问题 代码如下: 如果您尝试运行此代码,您可以看到扩展JavaScript字符串和JQuery.ajax,javascript,jquery,ajax,Javascript,Jquery,Ajax,最近两天,我试图理解代码中的一个问题 代码如下: 如果您尝试运行此代码,您可以看到 TypeError: undefined is not a function // of course, coz this === window 我试图找到“为什么”。我发现: 问题出在$.extend(如果第二个参数是object,则没有例外) 如果运行$.extend而不运行$.ajax,则一切正常 Jquery源代码中没有关于大写的内容 因此,问题是-如何以及为什么String.capitalize()
TypeError: undefined is not a function // of course, coz this === window
我试图找到“为什么”。我发现:
$.extend
(如果第二个参数是object,则没有例外)$.extend
而不运行$.ajax
,则一切正常
String.capitalize()
运行
另外,我知道,我知道,扩展本机类非常糟糕。有几件事:
toUpperCase()
是JavaScript。例如,请参见console.log('hello'.capitalize())代码>
数据:{“hello”,“world”}
作为$.ajax()调用的一部分
错误是由$.extend()的第二个参数是字符串而不是对象引起的。通过调试代码,您可以看到,在使用extend with empty选项时,它将转到jquery源代码(版本2.0.1)中的第201行
如果在这里放置断点,则在调用ajax extend时。参数的长度为2。一个是{},另一个是“”
控制台中的输出:
大写
大写2
test2
这就意味着你只需要遍历可枚举的属性
在此处检查JSFIDLE:
来自mozilla:
for..in语句迭代
对象,按任意顺序。对于每个不同的属性,可以使用语句
被处决
因此,如果您将大写方法定义为
Object.defineProperty(String.prototype, 'capitalize',
{
value: function(){ return this.charAt(0).toUpperCase() + this.slice(1); },
enumerable: false
});
它不会出现在ajax数据中。要在注释中回答您的问题:唯一的问题是String.capitalize如何运行以及为什么运行,
如果您看到jquery,它将获取每个数据键(foreach(数据中的东西)),并尝试用它创建一个查询字符串
如果它是一个函数,它将调用它(注释来自jquery源代码):
SSA的答案可能是一个解决方案,但Object.defineProperty只适用于。您正在以正确的方式使用$.extend()
。此函数接受这两个参数作为键值对象。调用capitalize
方法是因为$.extend({},”)
返回一个具有名为capitalize()的属性的对象。。。ajax方法将调用作为data
键的一部分传递的函数。。在这种情况下,capitalize
的值是一个由ajax框架调用的函数-现在的问题是为什么要将capitalize
属性复制到数据
中,而字符串
的其他原型
属性没有复制我知道第二个参数应该是一个对象,唯一的问题是如何以及为什么String.capitalize
运行,我就是找不到它在jquery源代码中运行的位置。要运行String.capitalize,您必须调用它。。。类似于$.extend({},{“hello”.capitalize(),“world”.capitalize()})的东西将给出{“hello”:“world”}。Prototype将函数添加到字符串的功能中,但它不会自动将其应用到每个字符串(另外,它是纯javascript,而不是jQuery——您正在使用jQuery作为javascript中的库)jquery将调用它,因为它是作为数据传递给ajax函数的。数据将接收每个不识字的成员,如果该成员是函数,它将调用它(大写)。这是不使用核心对象的另一个原因。您不拥有这些对象,因此您正在破坏封装:
$.ajax({
url: '/',
data: $.extend({}, {"hello":"world"})
})
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.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);
}
Object.defineProperty(String.prototype, 'capitalize',
{
value: function(){ return this.charAt(0).toUpperCase() + this.slice(1); },
enumerable: false
});
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 );
};