为什么输出如下?

时间:2012-08-17 14:37:13

标签: javascript jquery

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' }

我想要得到“一个”“两个”“三个”,但我得到以下奇怪的结果,任何人都可以解释?

6 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分: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/

认为这是一个怪癖。

更多阅读

答案 2 :(得分: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,即使它是一个简单的字符串或数字值。

“严格模式”(仅适用于现代Web浏览器,因此不适用于IE:http://caniuse.com/#feat=use-strict)实际上会更改此行为并允许this成为原语(这在规范中有记录:{ {3}}):

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

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

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

答案 3 :(得分: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"的字符串文字是没有函数的原始数据类型。但是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

答案 4 :(得分:0)

由于这个是一个对象,您只需使用toString方法输出其内容。

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

答案 5 :(得分:0)

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

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

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

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

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

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

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

它是:它不是将函数作为方法应用,而是jQ现在将键和值对作为参数传递,其中i是键,v是值。