avaScript中的数据类型非常灵活;将一种类型转为另外一种数据类型,如:将string类型的1转换为数字类型的1;
为什么要进行类型转换:因为数据之间的运算需要是同类型的运算,如果不同类型进行运算,需要将其转换为同一种类型后再进行运算。
类型转换分为两种:强制类型转换和自动类型转换;
1)自动转换:
在运行过程中根据运算的语意环境,会自动进行类型转换;
var a="2",b="1";
console.log(a-b);
b=true;
console.log(a-b);
注:最经典的是用在if语句中的条件中:
var car=new Object();
if(car){
console.log("汽车");
}
数据类型转换
2)强制(显式)类型转换:
尽管JavaScript可以自动进行类型转换,但有时仍需要显示转换,或者有时为了使代码变得更加清晰易读。
使用String()、Number()、Boolean()等函数强制转换;
a)转换为数值:
有3个函数可以把非数值转换为数值:Number()、parseInt()、parseFloat();Number()可以用于任何类型,而另外两个则专门用于把字符串转换成数值;这三个函数对于同样的输入会有不同的返回结果;
Number()函数:转换规则如下:
如果是Boolean值,true和false分别被转换为1和0;
如果是数字值,会直接返回该数值;
如果是undefined,返回NaN;
如果是null,返回0;
如果是字符串,则遵循以下规则:如果字符串中只包含数字(包括前面的正号或负号),则将其转换为十进制数,如“123”会变成123,而“011“会变成11(注:前导零忽略了);如果字符串中包含有效的浮点格式,如”1.1“,会被转换为浮点数值(同样,也忽略前导零);如果字符串包含有效的十六进制格式 ,如”0xf“,则被转换为相同大小的十进制数;会忽略字符串前面的空格;如果字符串是空的(不包含任何字符),则转换为0;如果字符串中包含除上述格式之外的字符,则被转换为NaN;
如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值;
一元操作符(+、-)的操作与Number()函数相同,会将操作数转换为数字;
var x="w";
console.log(typeof +x); // 等价于 x - 0
parseInt()和parseFloat()函数:
由于Number()函数在转换字符串时比较复杂而且不够合理,并且只能基于十进制数进行转换,且不能出现非法的尾随字符,因此在处理整数的时候更常用的是parseInt()和parseFloat()函数;
二者是全局函数,不从属于任何对象的方法;
其在转换时,更多的是看其是否符合数值模式;它会忽略字符串前面的空格,直到找到第一个非空字符;如果第一个字符不是数字字符或者负号,其会返回NaN,即parseInt()转换空字符串时会返回NaN(Number不会);如果第一个字符是数字,parseInt()会继续解析第二个字符,直到解析完后续所有字符或遇到到一个非数字字符;如:
console.log(parseInt("123red")); // 123
console.log(parseInt(" 8a")); // 8
console.log(parseInt(22.5)); // 22
console.log(parseInt("wang")); // NaN
console.log(parseInt("")); // NaN
parseInt()可以识别出十六进制数,识别不了八进制,在解析八进制时,去除零转换为十进制;
console.log(parseInt("0xAF")); // 10*16 + 15=175
console.log(parseInt(" 0xAFwangwei")); // 175
console.log(parseInt("070")); // 70
parseInt()在识别八进制时,第3版可以识别,但第5版识别不了,为了解决这个问题,可以为parseInt()指定第二个参数:转换基数,如:
console.log(parseInt("0xAF",16)); // 175
console.log(parseInt("070",8)); // 56
在指定了进制后,字符串可以不带前面的“0x“或“0”,如:
console.log(parseInt("AF",16)); // 175
console.log(parseInt("70",8)); // 56
注:当然除了八进制,十六进制,还可以指定其他进制;如:
console.log(parseInt("11",2)); // 1*2 + 1=3
console.log(parseInt("ff",16)); // 15 * 16 + 15=255
console.log(parseInt("zz",36)); // 35 * 36 + 35=1295
console.log(parseInt("077",8)); // 7 * 8 + 7=63
console.log(parseInt("077",10)); // 7 * 10 + 7=77
与parseInt()类似,parseFloat()也是如此,但如果字符串里有两个小数点,第二个小数点就是无效的了。
console.log(parseFloat("22.23.5")); // 22.23
parseFloat()只能解析十进制数,会忽略字符串的前导零,即十六进制数会被始终转换成0;
如果字符串包含的是一个可解析为整数的值,或者小数点后是零,parseFloat()会返回整数;
console.log(parseFloat("123abc")); // 123
console.log(parseFloat("123.56abc")); // 123.56
console.log(parseFloat("0xA")); // 0
console.log(parseFloat("22.5")); // 22.5
console.log(parseFloat("0909.5")); // 909.5
console.log(parseFloat("3.125e6")); // 3125000
b) 转换为字符串:
要把一个值转换为一个字符串有两种方式;第一种是使用几乎每个值都有的toString()方法;该方法会返回相应值的字符串;
var age=18;
var ageString=age.toString();
var found=true;
console.log(found); // "true" ,实际上调用了:found.toString()或found.valueof();
注:数值、布尔值、对象和字符串值都有toString()方法,但null和undefined值没有这个方法;
可以为toString()指定一个可选的基数(radix)的参数;默认情况下,toString()方法以十进制格式返回数值的字符串表示;通过设置基数,可以输出其他进制表示的字符串;如:
var age=18;
console.log(age.toString(2)); // 10010
console.log(age.toString(8)); // 22
console.log(age.toString(16)); // 12
第二种方法:使用String(),这个函数可以将任何类型的值转换为字符串,包括null或undefined;
转换规则:如果值有toString()方法,则调用该方法(没有参数);如果值是null,则返回null;如果是undefined,则返回undefined;
console.log(String(null)); // null
console.log(String(undefined)); // undefined
如果要把某个值转换为字符串,可以使用加号操作符把它与一个空字符串拼接。
var str=10 + "";
console.log(typeof str); // string
c)转换为Boolean:
可以使用转型函数Boolean(),如:var message="zero"; alert(Boolean(message));
使用Boolean(),会返回一个Boolean一个值,但返回的值是true还是false,取决于要转换值的数据类型及其实际值;
转换为Boolean类型值
这些转换规则一般用在控制语句(如if语句)自动执行相应的Boolean转换,如:
var msg="zero";
if(msg){
console.log(msg);
}
一元“!”运算符也将其操作数转换为布尔值并取反,这是在代码中进行这种类型转换的惯用用法:
var x="w";
console.log(!!x); // 等价于 Boolean(x)
检测类型:
typeof操作符:
ECMAScript中的数据是松散类型的,因此需要有一种方法来检测给定的变量的数据类型:typeof,其会返回以下字符串:
undefined值未定义、boolean布尔值、string字符串、number数值、object对象或null、function函数;
var msg="zeronetwork";
console.log(typeof msg);
console.log(typeof(msg));
console.log(typeof 18);
说明:typeof是一个操作而非不是一个函数,因此可以不使用括号;
注:有时typeof会返回一个令人迷惑但技术上却正确的值,如:typeof null,会返回object,因为特殊值null被认为是一个空的对象引用;
注:从技术角度来说,函数在ECMAScript中是对象,不是一种数据类型;然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。
instanceof操作符:
虽然typeof是个非常有用的工具,但是在检测引用类型的值时,用处不大;有时,想确认一个对象具体是什么类型的对象,就需要使用instanceof操作符了;
语法:result=variable instanceof constructor
如果变量是引用类型的实例,其会返回true,如:
var num=1;
console.log(num instanceof Number);
var person=new Object();
console.log(person instanceof Object);
var color=new Array();
alconsole.log(color instanceof Array);
var pattern=new RegExp();
console.log(pattern instanceof RegExp);
说明:根据规定,所有引用类型的值都是Object的实例;因此,在检测一个引用类型值和Object构造函数时,instanceof操作符始终会返回true;
使用instanceof操作符在检测基本类型的值,会返回false,因为基本类型不是对象。
Web前端开发之Javascript-零点程序员-王唯
JavaScript是一种动态类型、弱类型语言,它在处理字符和字符串时表现出了独特的灵活性和复杂性。在本文中,我们将从探讨JavaScript中的一段通过隐式类型转换的看似疯狂但有效的代码片段到熟知Javascript中的隐式类型转换规则
JavaScript的灵活性和隐式类型转换能力使得一些看似不合理的代码片段实际上是有效的。一个典型的例子就是以下代码:
// a
(![]+[])[+!![]]==="a"
符号运算规则[]空数组,在JavaScript中被视为真值(truthy)。尽管它是一个空数组,但它的存在本身就表示为真。!逻辑非(NOT)运算符,将其操作数的布尔值取反。结果是一个布尔值。!!双重逻辑非操作,将其操作数转换为布尔值。这是一个常见的技巧,用于将任何值转换为布尔值。+加号运算符不仅用于数值相加,当其一个操作数是字符串或可以转换为字符串时,JavaScript会将另一个操作数也转换为字符串,然后进行字符串连接操作。
符号运算过程运算结果![]空数组 [] 在JavaScript中被视为真值(truthy)。对其进行逻辑非操作 !,结果是 false(false+[])[+!![]]![] + []![] 的结果是 false,与空数组 [] 进行字符串连接操作,结果是 "false"("false")[+!![]]!![]布尔值 true("false")[+true]+!![]将布尔值 true 转换为数值 1("false")[1](![]+[])[+!![]]("false")[1] 获取字符串 "false" 的第 1 个字符(从 0 开始计数),结果是字符 "a""a"
通过这个例子,我们可以看到JavaScript的灵活性和强大的隐式类型转换能力。尽管这些代码片段看起来很疯狂,但它们确实是有效的,并且展示了JavaScript独特的特性和魅力。通过使用这六个字符(!, (, ), [, ], +),我们可以构建出各种各样的代码表达式。大家可以使用这个网站 JSF u ck 来自行尝试更多的组合和表达式。比如:
JSF u ck中,用了7455个字符来构建'z', 我们可以看出,逐个解析对于开发人员来说是十分困难的,它的可读性很差且难以让人理解,所以我们在日常开发中都不会像这样来写代码,但是我们为了增加开发效率和避免一些隐式类型错误问题,我们仍需要去熟悉常见的隐式类型转换,以下是一些隐式类型转换的规则。
在算术运算符中,只有字符串与运算符‘+'一起进行转换时,会转换成字符串,其他情形下均转换成数字
// +运算符和字符串一起,均转换成字符串
console.log(1 + '1') // '11'
// 其他
console.log(1 + true) // 2 : number + boolean
console.log(true + false) // 1 : boolean + boolean
console.log(1 - false) // 1 : number - boolean
console.log(true - false) // 1 : boolean - boolean
console.log(-1 * '1') // -1 : number * string
console.log(-1 / true) // -1 : number / boolean
console.log(2 ** ('1' + 0))// 1024 : number ** (string + number)
console.log(100 % ('1' + 0))// 0 : number % (string + number)
逻辑运算符中,运算符非(|)会转换成布尔值,而运算符或(||) 和 与(&&)会进行真/假值判断, 或(||)第一个为假输出第二个值,第一个为真输出第一个值。与(&&)第一个为真输出第二个值,第一个为假输出第一个值
// 非(!)
console.log(!true) //false
console.log(![]) // false
console.log(!!{}) // true !{} 会调用{}的valueOf 和 toString, 转换成[object object]
// 或(||) 和 与(&&)
console.log(0 || 1) // 1
console.log(1 || 0) // 1
console.log(0 && 1) // 0
console.log(1 && 0) // 0
位运算符 与(&),或(|),异或(*),取反(~),左移(<<),右移(>>)均会进行二进制值的转换
console.log(2 & 3) // 2 (010 & 011=> 010)
console.log(2 | 3) // 3 (010 | 011=> 011)
console.log(2 ^ 3) // 1 (010 ^ 011=> 001)
console.log(~2) // -3 (00000010=>11111101=> 11111100(-1取反码)=> 00000011(按位取反)=> -3)
console.log(2 << 1) // 4 (010 << 1=> 100=> 4)
console.log(4 >> 1) // 2 (100 >> 1=> 010=> 2)
在javaScript中,对象在需要转换为基本类型时,会调它们的tostring()或者valueof()方法。
操作数类型运算符转换规则示例object + string+调用 valueOf() 和 toString() 方法({}) + '' 结果为 "[object Object]"object - number-调用 valueOf() 方法转换为数字({valueOf() { return 3; }}) - 1 结果为 2
let obj={
toString() {
return '42';
},
valueOf() {
return 10;
}
};
console.log(obj + 10); // 输出 52
console.log(String(obj)); // 输出 '42'
解析:当对象参与加法运算时,JavaScript会调用valueOf() 方法获取基本类型值。在字符串上下文中,则会调用toString()方法。
Symbol 是 ES6 引入的一种新的原始数据类型,用于创建唯一的标识符。Symbol 类型的值在转换为字符串或数字时,会抛出错误
let sym=Symbol('example');
try {
console.log('symbol: ' + sym); // 抛出 TypeError
} catch (e) {
console.log(e); // TypeError: Cannot convert a Symbol value to a string
}
try {
console.log(sym + 10); // 抛出 TypeError
} catch (e) {
console.log(e); // TypeError: Cannot convert a Symbol value to a number
}
try {
console.log(String(sym)); // 'Symbol('example')'
} catch(e) {
console.log(e);
}
解析:Symbol 类型的值在隐式转换为字符串或数字时会抛出错误,必须显式转换
console.log([] + 1); // 输出 '1'
console.log([1] + 1); // 输出 '11'
console.log([1,2] + 1); // 输出 '1,21'
解析:空数组转换为字符串为 '',与数字 1 相加结果为 '1'。数组 [1] 转换为字符串为 '1',数组 [1,2] 转换为 '1,2',与数字 1 相加结果为 '1,21'。
console.log({}==true); // 输出 false
console.log({}==false); // 输出 false
console.log([]==true); // 输出 false
console.log([]==false); // 输出 true
解析:与boolean值比较,两边都转换成数字, 这时{}会转换成[object object]最后转数字成NaN。空数组 [] 转换为布尔值为 true,但与 false 比较时,会首先转换为数字 0,所以结果为 true。
console.log(undefined + 1) // NaN
console.log(null + 1) // 1
console.log(undefined==null)// true
解析:undefined 没有数值形式,所以当undefined + 1时,尝试将undefined转换为数字失败,结果为NaN. Null 在算术运算过程中,会被当作0,所以结果为1。当用'=='进行比较时,javascript会将它们视为相等,因为他们都是"无"或者"空"的特殊值。
在复杂的条件语句中,隐式类型转换也可能导致意外结果
let jsonStr='{"a": 1, "b": "2"}';
let obj=JSON.parse(jsonStr);
console.log(obj.a + obj.b); // 输出 '12'
解析:JSON.parse 将 JSON 字符串转换为对象,但对象属性 b 仍为字符串,与数字属性 a 相加时进行字符串拼接。
在复杂的条件语句中,隐式类型转换也可能导致意外结果
let x=0;
let y='0';
if (x==y) {
console.log('x==y'); // 会输出
}
if (x===y) {
console.log('x===y'); // 不会输出
}
if (x || y) {
console.log('x || y'); // 会输出
}
解析:在 x==y 中,JavaScript 会将 y 转换为数字 0,结果为 true。在 x || y 中,x 为假值(false),但 y 为真值(非空字符串 '0'),结果为 '0'。
以上内容展示了JavaScript中隐式类型转换的强大与复杂性,以及如何利用这些特性构建出看似疯狂但有效的代码片段。了解这些规则和陷阱对于编写健壮的JavaScript代码至关重要。
作者:唐亚婷
来源-微信公众号:大转转FE
出处:https://mp.weixin.qq.com/s/5jPYIRE0UjXqZSq5ikglrA
用Ueditor 上传视频成功了 预览也可以 但在再次编辑回显内容 准备修改时 发现 视频的小logo 不见了,用查看html发现src根本就没有值 链接在保存的过程丢失了
工具/原料
方法/步骤
注意事项
*请认真填写需求信息,我们会在24小时内与您取得联系。