锁定老帖子 主题:无处不在的隐式类型转换
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-22
最后修改:2010-07-25
如果把通过函数或方法调用,明确的将某种类型转换成另一种类型称为显示转换 ,相反则称为隐式类型转换 。google和维基百科中没有找到“显示类型转换”,“隐式类型转换”的字眼。暂且这么称呼。
一、 运算中存在的隐式类型转换
1, “+”运算符
var a = 11, b = '22'; var c = a + b;
这里引擎将会先把a变成字符串"11"再与b进行连接,变成了"1122"。
var a = 11; alert(typeof a); //-->number a = a + ''; alert(typeof a); //-->string
2,“-”运算符
“-”可以是一元运算符(取负),也可以是二元(减法运算)的。如
var a = 11, b = '5'; var c = a - b; alert(typeof c); //--> number
这里与上面的“+”相反,会把字符串b隐式的转换成数字5再进行算术减法运算。利用这个特性,可以很方便的将String转换成Number
var a = '11'; a = a - ''; alert(typeof a);// -->number 二、 语句中存在的隐式类型转换
1,if
var obj = {name:'jack'} if(obj){ //do more } 这里会把obj隐式的转换成Boolean类型
2,while
var obj = {name:'jack'} while(obj){ //do more } 同if
3,for in时的类型转换
定义对象字面量时发生从标识符到字符串的隐式转换。
var person = {'name':'jack',"age":20,school:'PKU'}; for(var a in person){ alert(a + ": " + typeof a); } 这里name,age分别加单/双引号以强调其为String类型,school没有加单/双引号。我们遍历下该对象的属性,查看其类型。发现school也被隐式的转换成了String类型。
var ary = [1,3,5,7]; for(var a in ary){ alert(a + ": " + typeof a); } 三、 alert时存在的隐式类型转换(这是群里猪婶婶发现的)
String.prototype.fn = function(){return this}; var a = 'hello'; alert(typeof a.fn()); //-->object alert(a.fn()); //-->hello
给String原型上添加了个fn方法,该方法返回this,我们知道this可以理解成当前类的实例对象,既然是对象那么typeof a.fn()自然返回是object了。
Number.prototype.fn = function(){return this}; var a = 10; alert(typeof a.fn());//-->object alert(a.fn()); //-->10
a.fn()返回的是对象类型,但在alert(a.fn())时会隐式的将其转换成数字。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-07-27
最后修改:2010-07-27
很少用减号来转化字符串为数字,到是用加号也可以。
var a = +"2"+1; //a=3 减号貌似有歧义,不好用! |
|
返回顶楼 | |
发表时间:2010-07-28
最后修改:2010-07-28
String.prototype.toString = function(){ return "真的是隐式转换?"; } String.prototype.fn = function(){return this}; var a = 'hello'; alert(typeof a.fn()); //-->object alert(a.fn()); alert(a.fn());时只是调用了String.prototype.toString而已..不是你说的什么隐式转换啦. |
|
返回顶楼 | |
发表时间:2010-07-28
引用 1,if
Js代码 var obj = {name:'jack'} if(obj){ //do more } 这里会把obj隐式的转换成Boolean类型 这里的转换规则比较特殊。首先判断类型,如果是布尔型,则用true/false来判断。如果是非布尔型。则按照对象来判断。如果对象==null(===null or ===undefined),则返回false,其他情况返回true var obj = null; if (obj) { alert(123); } |
|
返回顶楼 | |
发表时间:2010-07-28
引用 alert时存在的隐式类型转换(这是群里猪婶婶发现的)
Js代码 String.prototype.fn = function(){return this}; var a = 'hello'; alert(typeof a.fn()); //-->object alert(a.fn()); //-->hello 给String原型上添加了个fn方法,该方法返回this,我们知道this可以理解成当前类的实例对象,既然是对象那么typeof a.fn()自然返回是object了。 关键是最后的alert(a.fn()),a.fn()返回的明明是对象,但却隐式的转换成了字符串“hello”显示。 同样的情况发生在数字类型上,如 Js代码 Number.prototype.fn = function(){return this}; var a = 10; alert(typeof a.fn());//-->object alert(a.fn()); //-->10 a.fn()返回的是对象类型,但在alert(a.fn())时会隐式的将其转换成数字。 这里只有一部分是隐士转换 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> String.prototype.toString = function() { return 1234; }; String.prototype.getName = function() { alert(1111); }; // 用new创建 var str = new String("test"); // 自动创建 var str2 = "4444"; // 1234 alert(str); // 4444 alert(str2); // 1111 str2.getName(); // 类 function Test() {} Test.prototype.toString = function() {return "test"}; // test alert(new Test()); </script> </head> <body> </body> </html> 一般情况下,我们在打印一个对象的时候,浏览器会自动调用对象的toString方法。而不用new创建出来的。不受这个条件约束 |
|
返回顶楼 | |
发表时间:2010-07-28
引用 ,for in时的类型转换
定义对象字面量时发生从标识符到字符串的隐式转换。 Js代码 var person = {'name':'jack',"age":20,school:'PKU'}; for(var a in person){ alert(a + ": " + typeof a); } 这里name,age分别加单/双引号以强调其为String类型,school没有加单/双引号。我们遍历下该对象的属性,查看其类型。发现school也被隐式的转换成了String类型。 数组的索引其实也是字符串类型。这着实令人惊叹,但事实的确如此。如 Js代码 var ary = [1,3,5,7]; for(var a in ary){ alert(a + ": " + typeof a); } javascript对象都是关联数组。关联数组的索引当然都是字符串。。。。 |
|
返回顶楼 | |
发表时间:2011-02-06
1.隐式类型转换的定义不明确,会让读者“浮想连篇”的。
2.if,for,while等语句的条件表达式,不要求是布尔表达式,只要是null,undefined,false,0,0.0,""中的任何一个,条件表达是就不成立(没有所谓的类型转换,这个就是规则)。 3.{'name':'jack',"age":20,school:'PKU'},对象定义完整的写法都应该在key上加双引号,只不过解释器做的高级一些,在“某些”条件下允许你简化之,所以也无所谓类型转换。还有标识符不是一种数据类型,JS语言中对象的key永远是字符串类型的(新的版本会不会超越这个规则不知道)。 4.很多时候很多人理解的很多的“默认类型转换”都与toString,valueOf这两个方法扯上关系。 5.C,C++等语言的强制类型转换发生在编译期,强类型语言的默认类型转换一般都是“无损”的(比如char->int,float->double),JS的类型转换只发生在运行期,因为这种弱类型语言的解析过程是不强调类型的。 |
|
返回顶楼 | |
发表时间:2011-02-06
两个测试用例:
//-----1 var a = { {}: 1 //IE6提示:缺少标识符、字符串或数字 //FF3提示:invalid property id //Chrome提示:Uncaught SyntaxError: Unexpected token { }; //-----2 var a = { 0.001: 1, 0.1e-2: 1, .1e-2: 1 }; for(var k in a){ alert(k + "=" + typeof(k)); //0.001 } 这两个测试用例能说明一些问题,可能会招来很多人对默认类型转换的讨论。我只想说,JS对象字面量是代码文本层面的概念,JS对象的key是内部实现层面的,代码文本层面允许标识符,字符串和数字,目的是为了能够准确得知内部实现层面的字符串的值。如果语法解析中的这种转换算作类型转换,那这个属于默认类型转换。 |
|
返回顶楼 | |
浏览 3178 次