2
var obj = [ "one", "two", "three"];

$.each(obj, function() {
   console.log(this);
});

我得到的输出是

{ '0': 'o', '1': 'n', '2': 'e' }
{ '0': 't', '1': 'w', '2': 'o' }
{ '0': 't', '1': 'h', '2': 'r', '3': 'e', '4': 'e' }

我想得到“一”“二”“三”,但我得到以下奇怪的结果,谁能解释一下?

4

6 回答 6

5

this始终是一个对象。字符串对象由键/值对组成,其中键是索引,值是字符串中该索引处的字符。尝试Object("foo")自己创建这样的对象。

通过使用严格模式,您可以抑制:

$.each(obj, function() {
  "use strict";
  console.log(this);
});
于 2012-08-17T14:39:43.467 回答
4

在 javascript(不仅仅是 jQuery)中,this是一个特殊关键字,指的是绑定到当前范围的对象(除非它已被更改)。在$.each函数内,循环函数(您传递的函数)的范围上下文绑定到您正在循环的项目。可能是这样,但它不可靠,也不是很有用或有趣。

观察:

var clams = { 'tomato!':'gross' };
var items = ["one", "two", "three"];


$.each(items, function (index, item) {
    console.log('this',this);
    console.log('item', item);    
}.bind(clams));

试试看:http: //jsfiddle.net/LBfet/

虽然可以this$.each循环中使用,但我建议按照文档提供的方式使用它,即您的循环函数支持签名callback(indexInArray, valueOfElement)

文档:http ://api.jquery.com/jQuery.each/

认为这是一个怪癖。

更多阅读

于 2012-08-17T14:51:11.097 回答
2

这里发生的是 jQuery用于将回调内部的.call值设置为.this$.each

调用时.call, 的值将this转换为对象(根据 JavaScript 规范:http ://es5.github.com/#x10.4.3 )。

jQuery 文档中也提到了这一点:http: //api.jquery.com/jQuery.each/

该值也可以通过this关键字访问,但 Javascript 将始终将this值包装为 Object,即使它是简单的字符串或数字值。

“严格模式”(仅适用于现代网络浏览器,因此不适用于 IE:http ://caniuse.com/#feat=use-strict )实际上改变了这种行为并允许this成为原始模式(这在规范中有记录:http://es5.github.com/#x15.3.4.4):

$.each(obj, function() {
  "use strict";
  console.log(this);
});

您还可以使用.valueOf()将对象转换回其各自的原语:

$.each(obj, function() {
  console.log(this.valueOf());
});
于 2012-08-17T15:00:34.483 回答
1

一个 javascript 字符串,归根结底,是一个对象。这个对象被分解成一个字符数组。这就是为什么您可以在字符串对象(如数组)上调用一些相同的函数的原因。

任何时候你操作一个字符串字面量,在这种情况下,它都会变成一个字符串对象。字符串对象是一个字符数组。这将允许在使用以下函数时轻松大写:toUpperCase() & toLowerCase() - (以及其他)

this正如其他人所说,使用被引用为对象。这里有一个小测试代码来展示一个字符串如何像一个数组:

var testStr = "test";
var obj = [ "one", "two", "three"];
console.log(testStr.charAt[1]); // Will return 'e'
console.log(testStr[1]); // Will return 'e'
console.log(obj[1]); // Will return 'two'
console.log(testStr.length) // Will return 4
console.log(obj.length) // Will return 3

在这种情况下,字符串文字var testStr = "string"是没有函数的原始数据类型。但是字符串对象用于使用函数和非原始数据类型来操作数据。

现在我将创建一个字符串对象并将其输出到控制台:( 当您操作字符串文字时会发生这种情况,它会被转换为字符串对象)

strTest = new String("TEST String");
console.log(strTest);

你会得到:

String
0: "T"
1: "E"
2: "S"
3: "T"
4: " "
5: "S"
6: "t"
7: "r"
8: "i"
9: "n"
10: "g"
length: 11
__proto__: String
    anchor: function anchor() { [native code] }
    big: function big() { [native code] }
    blink: function blink() { [native code] }
    bold: function bold() { [native code] }
    camelCase: function (){return this.replace(/-\D/g,function(match){return match.charAt(1).toUpperCase();});}
    capitalize: function (){return this.replace(/\b[a-z]/g,function(match){return match.toUpperCase();});}
    charAt: function charAt() { [native code] }
    charCodeAt: function charCodeAt() { [native code] }
    checkAllAvailableTags: function (){var b=this,d;for(d in c)c.hasOwnProperty(d)&&(b=b.replace(d,c[d]));return b}
    clean: function (){return this.replace(/\s{2,}/g,' ').trim();}
    concat: function concat() { [native code] }
    constructor: function String() { [native code] }
    contains: function (string,s){return(s)?(s+this+s).indexOf(s+string+s)>-1:this.indexOf(string)>-1;}
    escapeRegExp: function (){return this.replace(/([.*+?^${}()|[\]\/\\])/g,'\\$1');}
    fixed: function fixed() { [native code] }
    fontcolor: function fontcolor() { [native code] }
    fontsize: function fontsize() { [native code] }
    hexToRgb: function (array){var hex=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);return(hex)?hex.slice(1).hexToRgb(array):false;}
    hyphenate: function (){return this.replace(/\w[A-Z]/g,function(match){return(match.charAt(0)+'-'+match.charAt(1).toLowerCase());});}
    indexOf: function indexOf() { [native code] }
    italics: function italics() { [native code] }
    lastIndexOf: function lastIndexOf() { [native code] }
    length: 0
    link: function link() { [native code] }
    localeCompare: function localeCompare() { [native code] }
    match: function match() { [native code] }
    replace: function replace() { [native code] }
    rgbToHex: function (array){var rgb=this.match(/\d{1,3}/g);return(rgb)?rgb.rgbToHex(array):false;}
    search: function search() { [native code] }
    slice: function slice() { [native code] }
    small: function small() { [native code] }
    split: function split() { [native code] }
    strike: function strike() { [native code] }
    sub: function sub() { [native code] }
    substr: function substr() { [native code] }
    substring: function substring() { [native code] }
    sup: function sup() { [native code] }
    test: function (regex,params){return(($type(regex)=='string')?new RegExp(regex,params):regex).test(this);}
    toFloat: function (){return parseFloat(this);}
    toInt: function (){return parseInt(this,10);}
    toLocaleLowerCase: function toLocaleLowerCase() { [native code] }
    toLocaleUpperCase: function toLocaleUpperCase() { [native code] }
    toLowerCase: function toLowerCase() { [native code] }
    toString: function toString() { [native code] }
    toUpperCase: function toUpperCase() { [native code] }
    trim: function trim() { [native code] }
    trimLeft: function trimLeft() { [native code] }
    trimRight: function trimRight() { [native code] }
    valueOf: function valueOf() { [native code] }
    __proto__: Object
于 2012-08-17T14:50:30.243 回答
0

由于是一个对象,您可以简单地使用 toString 方法来输出其内容。

$.each( obj, function() {
    console.log( this.toString() );
});
于 2012-08-17T14:52:36.910 回答
0

为什么输出是这样的:正如 pimvdb 所说:这是一个指向对象的指针。jQuery匿名函数作为回调应用到每个值。如果那个值不是一个对象,jQ 会将它变成一个对象。因此,记录了三个对象。

再加上字符串对于计算机来说是最难处理的事情之一!它只是一系列(数组)字符。这就是为什么在 C 和许多其他语言中字符串类型不(不)存在的原因。字符串是一个数组,因为数组是 JavaScript 中的扩充对象(第一个版本甚至没有),所以你会得到你得到的输出。
不过,这并不是什么大问题:

obj = [ "one", "two", "three"];

$.each(obj, function()
{
   console.log(this+'');
});

解决了这个问题(有点)。但是 add typeof this,你会看到它仍然是一个对象, add this instanceof String,你会得到真实的。要摆脱那些讨厌的字符串对象(它们很讨厌),并获得干净的字符串常量:

obj = [ "one", "two", "three"];

$.each(obj, function(i,el) {
   console.log(el);
});

就是这样:jQ 不再将函数作为方法应用,而是将键和值对作为参数传递,其中 i 是键,v 是值。

于 2012-08-17T14:52:41.107 回答