JavaScript学习(四):JavaScript类型转换以及变量作用域

2024-09-05 11:32

本文主要是介绍JavaScript学习(四):JavaScript类型转换以及变量作用域,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.8 类型转换
JavaScript中的取值类型非常灵活,从布尔值可以看到这一点:当JavaScript期望使用一个布尔值的时候,可以提供任何值,JavaScript将根据需要自行转换类型,真值转换成true,假值转换成false




3.8.1 转换和相等性
因为JavaScript可以做灵活的类型转换,因此“=="相等运算符也随相等的含义灵活多变。
null == undefined   //true
"0" == 0  //true
0 == false  //true
"0" == false  //true
*需要注意的是,一个值转换成另一个值并不意味着两个值相等,比如,在期望使用布尔值的地方使用了undefined,undefined会转换成false,但并不表明undefined == false.



3.8.2 显式类型转换
尽管JavaScript可以自动做许多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显式转换。
做显式类型转换最简单的方法就是使用Boolean()、Number()、String()或Object()函数。(除了null和undefined之外任何值都具有toString()方法,这个方法执行结果通常和String()方法返回的结果是一样的)
JavaScript中提供了专门的函数和方法用来做更精确的数字到字符串(number-to-string)和字符串到数字(string-to-number)的转换。
Number类定义的toString()方法可以接收表示转换基数的可选参数(二、八、十等进制数),如果不指定此参数,转换规则将是基于十进制。
var n = 17;
binary_string = n.toString(2); //"10001"
octal_string = "0" + n.toString(8); // "021"
hex_string = "0x" + n.toString(16); //"0x11"
控制输出中小数点位置和有效数字位数,或者决定是否需要指数计数法。
toFixed()---根据小数点后的指定位数将数字转换成字符串,不使用指数记数法。
toExponential()----使用指数记数法将数字转换成指数形式的字符串,其中小数点前只有一位,小数点后的位数则由参数决定(有效数字位数比指定位数多一位)。
toPrecision()----根据指定的有效数字位数将数字转换成字符串,如果有效数字的位数少于数字整数部分的 位数,则转换成指数形式。
var n = 123456.789;
n.toFixed(0); // "123457"
n.toFixed(2); //"123456.79"
n.toFixed(5);  // "123456.78900"
n.toExponential(1); //"1.2e+5"
n.toExponential(3); //"1.235e+5"
n.toPrecision(4);  //"1.235e+5"
n.toPrecision(7); //"123456.8"
n.toPrecision(10); //"123456.7890"
通过Number()转换函数传入一个字符串,它会试图将其转换成一个整数或浮点数直接量,这个方法只能基于十进制数进行转换,并且不能出现非法的为尾随字符。
parseInt()和parseFloat()(全局函数,不从属于任何类的方法).parseInt()值解析整数,而parseFloat()则可以解析整数和浮点数,如果字符串前缀是“0x”或者“0X”,parseInt()将其解释为十六进制数,parseInt和parseFloat都会跳过任意数量的前导空格,尽可能解析更多数值字符,并忽略后面的内容。如果第一个非空格字符是非法的数字直接量,将最终返回NaN;
parseInt可以接收第二个可选参数,这个参数指定数字转换的基数,合法的取值范围是2-36.

parseInt("3 blind mice ");  // 3
parseFloat(" 3.14 meter");  //3.14
parseInt(" -12.34");  //-12
parseInt("0xFF"); // 255
parseInt("0.1");  //0
parseInt("11",2); // 3
parseInt("ff",16);  //255
parseInt(".1");  //NaN:整数不能以.开头

parseFloat(".1"); //0.1
parseFloat("$72.74");  //数字不能以$开头




3.8.3 对象转换成原始值

对象到布尔值:所有对象均转换成true,包装对象也是如此,new Boolean(false)是一个对象而不是原始值,将转换成true。
*本地对象、内置对象、宿主对象: http://www.w3school.com.cn/js/pro_js_object_types.asp
宿主对象根据各自的算法可以转换成字符串和数字,此下的规则只适用于本地对象。
所有对象都继承了两个方法。
  1.     toString()----返回一个反映这个对象的字符串
很多类定义了更多版本的toString()方法。
数组(Array class)的toString()方法将每个数组元素转换成一个字符串,并在元素之间添加逗号后合并成结果字符串。
函数类(Function class)的toString()方法返回这个函数的实现定义的表示方式,实际上就是把函数转换成JavaScript源代码字符串。
日期类定义的toString()方法返回一个可读的日期和时间字符串
RegExp()定义的toString()方法将RegExp对象转换为表示正则表达式直接量的字符串:
({x:1 , y:2}).toString() //"[object Object]"
[1,2,3].toString()  //"1,2,3"
var fx = function (x){return x;};
fx.toString()  //"function (x){return x;}"
new Date().toString()  //"Mon Nov 09 2015 07:57:44 GMT+0800"
new RegExp(/\d+/g).toString() //"/\d+/g"

2.   valueOf()---存在任意原始值,默认将对象转换成它的原始值;对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单的返回对象本身,而不是返回一个原始值。
数组、函数、正则表达式简单的继承了此方法,调用这些类型的实例的valueOf()方法只是简单的返回对象本身。日期类定义的valueOf()方法会返回它的一个内部表示:1970年一月一日以来的毫秒数。
({x:1 , y:2}).valueOf() //Object { x=1,  y=2}
[1,2,3].toString()  //[1,2,3]
var fx = function (x){return x;};
fx.toString()  //"function (x)"
new Date().valueOf()  //1447028184881
new RegExp(/\d+/g).valueOf() //RegExp /\d+/g


JavaScript对象到字符串的转换:
  • 如果对象具有toString()方法,则调用此方法。如果它返回一个原始值,JavaScript将这个原始值转换成字符串(如果本身不是字符串的话),并返回字符串结果。
  • 如果没有toString()方法,或者这个方法不返回一个原始值,那么JavaScript会调用valueOf()方法,如果存在这个方法,则JavaScript调用它,如果返回原始值,JavaScript将这个值转换成字符串(如果本身不是字符串的话),并返回字符串结果。
  • 否则,JavaScript将无法从toString或者valueOf获得一个原始值,因此它将抛出一个类型错误异常。
JavaScript对象到数字的转换,会首先尝试使用valueOf方法:
  • 如果对象具有valueOf()方法,后者返回一个原始值,则JavaScript将这个原始值转换成数字并返回这个数字
  • 否则,如果对象具有toString方法,后者返回一个原始值,则JavaScript将其转换并返回
  • 否则,JavaScript抛出一个类型错误异常。

例如:[]转换数字会被转换成0,[1,2,2]会被转换成1
数组继承valueOf,返回一个对象,不是原始值,尝试使用toString()方法,空数组返回空字符串,转换成数字为0,含有元素的数组转换成对应的字符串,转换成相应的数字。


JavaScript中的“+”运算符可以进行数学加法和字符串连接操作,如果其中一个是对象,则JavaScript使用特殊的方法将对象转换成原始值(“==”类似)。
JavaScript运算符中的类型转换根据实际情况而定,例如“-”是把两个操作数都转换成数字。
日期类是JavaScript语言核心中唯一的预先定义类型,它定义了有意义的向字符串和数字类型的转换,视情况而定。
对于所有的非日期类对象来说,对象到原始值的转换基本上都是对象到数字的转换,但是这里的转换:通过valueof和toString方法返回的原始值都将被直接使用,而不会被强制转换成数字或者字符串。
var now = new Date();
typeof(now + 1);  // "string"
typeof(now - 1);   // "number"
now == now.toString();  // true:日期转字符串
now > now - 1;   //true:日期转换数字


3.9 变量声明
在JavaScript中,使用一个变量之前都应当声明,变量是使用var关键字来声明的:
var i;  
也可以通过一个var关键字声明多个对象:
var i , sum;
还可以将变量的声明和初始赋值结合在一起:
var i = 0 , j = 1;
如果未在var声明语句中给变量指定初始值,那么这个变量在未赋值之前就是undefined。
在JavaScript中,变量可以是任意数据类型。


3.10 变量作用域
一个变量的作用域是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。在函数内声明的变量只在函数内有定义。它们是局部变量,作用域是局部的。函数参数也是局部变量,它们只在函数体内有定义。
在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就会被局部变量所遮盖。

3.10.1 函数作用域和声明前提
JavaScript没有块级作用域,只有函数作用域:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

function test(o){
var i = 0;
if(typeof o == "object"){
var j = 0;
for(var k = 0; k < 10; k++){
}
console.log(k);   // k已经定义了 输出10
}
console.log(j);   // j以及定义  输出0
}
test([1,2]);
// 10  0

JavaScript的函数作用域是指函数内声明的所有变量在函数体内始终是可见的,这意味着变量在声明之前甚至已经可用,JavaScript这个特性被非正式的称为----声明前提,即在JavaScript函数里声明的所有变量(但不涉及赋值)都被“提前”至函数体的顶部。
var scope = "global";
function f(){
console.log(scope);  // undefine
var scope = "local"; //变量在这赋值,但是在函数体内任何地方均是有定义的
console.log(scope); // local
}
f();

因为函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖住了同名全局变,但是没赋值之前均是undefined。等同于:
var scope = "global";
function f(){
var scope;
console.log(scope);  // undefine
scope = "local"; //变量在这赋值,但是在函数体内任何地方均是有定义的
console.log(scope); // local
}
f();
尽量将变量声明放在函数顶部。

这篇关于JavaScript学习(四):JavaScript类型转换以及变量作用域的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138837

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B