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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06