JavaScript之全局函数详解

Posted 白大锅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript之全局函数详解相关的知识,希望对你有一定的参考价值。


前言

今天在搬砖的时候页面上有个根据传过来的算法通过js全局函数eval()进行计算的js需求 属实有被恶心到 今天博主就整理下JavaScript的全局函数 防止以后再被这种问题使绊子 也希望对大家有所帮助

一、JavaScript全局函数有哪些?

函数描述
decodeURI()解码某个编码的 URI。
decodeURIComponent()解码一个编码的 URI 组件。
encodeURI()把字符串编码为 URI。
encodeURIComponent()把字符串编码为 URI 组件。
escape()对字符串进行编码。
eval()计算 JavaScript 字符串,并把它作为脚本代码来执行。
isFinite()检查某个值是否为有穷大的数。
isNaN()检查某个值是否是数字。
Number()把对象的值转换为数字。
parseFloat()解析一个字符串并返回一个浮点数。
parseInt()解析一个字符串并返回一个整数。
String()把对象的值转换为字符串。
unescape()对由 escape() 编码的字符串进行解码。

二、JavaScript全局函数详解?

2.1.Eval()

2.1.1.例子一

首先看示例:

eval("x=10;y=20;document.write(x*y)");
document.write("<br>" + eval("2+2"));
document.write("<br>" + eval(x+17));

结果:

200
4
27

特殊用法{}:

document.write("<br>" + eval{3+3}));

这时返回结果为:6 我们发现{}这样使用和()其实是一样的 不同在于:

//{}/2 这种写法是不支持的
document.write("<br>" + eval{3+3}/2));
//()是可以的
document.write("<br>" + eval(3+3)/2));
//若是{}也想进行此类计算也可以 如下:
document.write("<br>" + eval{(3+3)/2}));

2.1.2.例子二

看一下在其他情况中,eval() 返回的结果:

eval("2+3")    // 返回 5
var myeval = eval;    // 可能会抛出 EvalError 异常
myeval("2+3");    // 可能会抛出 EvalError 异常

可以使用下面这段代码来检测 eval() 的参数是否合法:

try  {
  alert("Result:" + eval(prompt("Enter an expression:","")));
}catch(exception) {
  alert(exception);
}

2.1.3.例子三(解析JSON字符串)

2.1.3.1.eval解析函数:

JSON 不允许包含函数,但你可以将函数作为字符串存储,之后再将字符串转换为函数。

var text = '{ "name":"Runoob", "alexa":"function () {return 10000;}", "site":"www.runoob.com"}';
var obj = JSON.parse(text);
obj.alexa = eval("(" + obj.alexa + ")");
 
document.getElementById("demo").innerhtml = obj.name + " Alexa 排名:" + obj.alexa();

2.1.3.2.JSON字符串转换为对象的两种方法

  //将JSON字符串转为JS对象的方法一
    var obj = JSON.parse('{ "name":"runoob", "alexa":10000, "site":"www.runoob.com" }');
    document.write(obj.name + "<br/>");
    //将JSON字符串转为JS对象的方法二
    //JSON格式的字符串
    var test1 = '{"name":"qlq","age":25}';
    var obj2 = eval("(" + test1 + ")"); //必须带圆括号
    document.write(obj2.name + "<br/>" + obj2.age);

结果:

runoob
qlq
25

为什么要 eval这里要添加 eval("(" + test1 + “)”)//”呢?

原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。

加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将 括号内的表达式(expression)转化为对象,而不是作为语 句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始 和结束标记,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:

alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]

对于这种写法,在JS中,可以到处看到。

如: (function()) {}(); 做闭包操作时等。

alert(dataObj.root.length);//输出root的子对象数量
$.each(dataObj.root,fucntion(idx,item){
if(idx==0){
return true;
}
//输出每个root子对象的名称和值
alert("name:"+item.name+",value:"+item.value);
})

注:对于一般的js生成json对象,只需要将$.each()方法替换为for语句即可,其他不变。

2.1.3.3.对于服务器返回的JSON字符串,如果jquery异步请求将 type(一般为这个配置属性)设为"json",或者利 用$.getJSON()方法获得服务器返回,那么就不需要eval()方法了,因为这时候得到的结果已经是json对象了,只需直接调用该对象即可,这里以$.getJSON方法为例说明数据处理方法:

$.getJSON("http://www.phpzixue.cn/",{param:"gaoyusi"},function(data){
//此处返回的data已经是json对象
//以下其他操作同第一种情况
$.each(data.root,function(idx,item){
if(idx==0){
return true;//同countinue,返回false同break
}
alert("name:"+item.name+",value:"+item.value);
});
});

这里特别需要注意的是方式1中的eval()方法是动态执行其中字符串(可能是js脚本)的,这样很容易会造成系统的安全问题。所以可以采用一些规避了eval()的第三方客户端脚本库,比如JSON in JavaScript就提供了一个不超过3k的脚本库。

2.1.3.4.补充:eval()解析的JSON的key可以不带""

一般的JSON的key必须带双引号,也就是类似于{"key":"vslue"}的形式,但是如果用eval("("+json+")")的形式解析字符串为JSON的时候,json可以写为{key:"value"}

2.2.decodeURI()与 decodeURIComponent() – 解码函数

decodeURI() 可对 encodeURI() 函数编码过的 URI 进行解码

如:

 const aaa = '#$ ¥%23ccc/'
  
  console.log(encodeURI(aaa));	// #$%20%EF%BF%A5%2523ccc/
  console.log(decodeURI(aaa));	// #$ ¥%23ccc/
  console.log(encodeURIComponent(aaa));	// %23%24%20%EF%BF%A5%2523ccc%2F
  console.log(decodeURIComponent(aaa));	// #$ ¥#ccc/

我们在获取地址栏参数是通常封装成如下函数:

export function getQueryObject(url) {
  url = url || window.location.href
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

2.3.encodeURI()与encodeURIComponent() — 编码函数

encodeURI():
语法

encodeURI(URIstring)
参数 描述
URIstring 必需。一个字符串,含有 URI 或其他要编码的文本。
返回值
URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。
说明
该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ’ ( ) 。
该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:;/?: @&=+$,#

encodeURIComponent() :

语法
encodeURIComponent(URIstring)
参数 描述
URIstring 必需。一个字符串,含有 URI 组件或其他要编码的文本。
返回值
URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。
说明
该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ’ ( ) 。
其他字符(比如 :;/?😡&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
提示和注释
提示:请注意 encodeURIComponent() 函数 与 encodeURI() 函数的区别之处,前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。

enCodeURI示例:

<html>
<body>

<script type="text/javascript">

document.write(encodeURI("http://www.w3school.com.cn")+ "<br />")
document.write(encodeURI("http://www.w3school.com.cn/My first/")+ "<br />")
document.write(encodeURI(",/?:@&=+$#"))

</script>

</body>
</html>

输出结果:

http://www.w3school.com.cn
http://www.w3school.com.cn/My%20first/
,/?: @&=+$#

对整个URL进行编码,而URL的特定标识符不会被转码。

encodeURIComponent() 示例:

<script type="text/javascript">

document.write(encodeURIComponent("http://www.w3school.com.cn"))
document.write("<br />")
document.write(encodeURIComponent("http://www.w3school.com.cn/p 1/"))
document.write("<br />")
document.write(encodeURIComponent(",/?:@&=+$#"))

</script>

输出结果:

http%3A%2F%2Fwww.w3school.com.cn
http%3A%2F%2Fwww.w3school.com.cn%2Fp%201%2F
%2C%2F%3F%3A%40%26%3D%2B%24%23

对URL中的参数进行编码,因为参数也是一个URL,如果不编码会影响整个URL的跳转。

2.4.escape()

语法
escape(string)
参数 描述
string 必需。要被转义或编码的字符串。
返回值
已编码的 string 的副本。其中某些字符被替换成了十六进制的转义序列。

说明
该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。
注意:ECMAScript v3 反对使用该方法,应用使用 decodeURI()decodeURIComponent() 替代它。

示例:

<script type="text/javascript">

document.write(escape("Visit W3School!") + "<br />")
document.write(escape("?!=()#%&"))

</script>

结果:

Visit%20W3School%21
%3F%21%3D%28%29%23%25%26

2.5.isFinite()

它的作用就是用来判断参数是否位于最小值和最大值之间,如果位于之间就会返回true,否则就会返回false。
在ECMAScript中能够表示的最小的数值保存在Number.MIN_VALUE中,在大多数浏览器中这个值是:5e-324;能够表示的最大的数值保存在Number.MAX_VALUE中,在大多数浏览器中,这个值是1.7976931348623157e+308,如果数值超出了范围,该值就会自动转换为一个特殊值infinity,正数的话前面会是Infinity,如果是负数的话会转换为-Infinity

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
		var num = 1123;
		alert(num);//1123
		var num1 = Number.MAX_VALUE+Number.MAX_VALUE;
		alert(num1);//Infinity
		alert(isFinite(num));//true
		alert(isFinite(num1));//false
		</script>
	</head>
	<body>
	</body>
</html>

可以用来判断该值是否在正常的数值范围内

2.6.isNaN()

定义和用法
isNaN() 函数用于检查其参数是否是非数字值。

isNaN的用法:检测当前值是否不是有效数字,返回true代表不是有效数字,返回false是有效数字

//=>语法:isNaN([value])
var num=12;
isNaN(num); //->检测num变量存储的值是否为非有效数字 false

isNaN('13') =>false
isNaN('你好呀') =>true
isNaN(true) =>false
isNaN(false) =>false
isNaN(null) =>false
isNaN(undefined) =>true
isNaN({age:9}) =>true
isNaN([12,23]) =>true
isNaN([12]) =>false
isNaN(/^$/) =>true
isNaN(function(){}) =>true

2.6.1.isNaN检测的机制:首先验证当前要检测的值是否为数字类型的,如果不是,浏览器会默认的把值转换为数字类型

[字符串转数字]
Number('13') ->13
Number('13px') ->NaN 如果当前字符串中出现任意一个非有效数字字符,结果则为NaN
Number('13.5') ->13.5 可以识别小数
[布尔转数字]
Number(true) ->1
Number(false) ->0
[其它]
Number(null) ->0
Number(undefined) ->NaN

把引用数据类型值转换为数字:先把引用值调取toString转换为字符串,然后再把字符串调取Number转换为数字

2.6.2.当前检测的值已经是数字类型,是有效数字返回false,不是返回true(数字类型中只有NaN不是有效数字,其余都是有效数字)

parseInt / parseFloat等同于Number,也是为了把其它类型的值转换为数字类型
和Number的区别在于字符串转换分析上

Number:出现任意非有效数字字符,结果就是NaN
parseInt:把一个字符串中的整数部分解析出来,parseFloat是把一个字符串中小数(浮点数)部分解析出来

parseInt('13.5px') =>13
parseFloat('13.5px') =>13.5
parseInt('width:13.5px') =>NaN 

从字符串最左边字符开始查找有效数字字符,并且转换为数字,但是一但遇到一个非有效数字字符,查找结束
因此,使用isNaN之前,最好判断一下数据类型。

function myIsNaN(value) {
  return typeof value === 'number' && isNaN(value);
}

判断NaN更可靠的方法是,利用NaN为唯一不等于自身的值的这个特点,进行判断。

function myIsNaN(value) {
  return value !== value;
}

2.7.Number()

Number(obj)为全局函数,不依托于任何对象,用于将参数对象的值转为数值
例如:

var test1= new Boolean(true);
var test2= new Boolean(false);
var test3= new Date();
var test4= new String("999");
var test5= new String("999 888");

document.write(Number(test1)); 输出 1
document.write(Number(test2)); 输出 0
document.write(Number(test3)); 输出 1256657776588
document.write(Number(test4)); 输出 999
document.write(Number(test5)); 输出 NaN

1.参数为string

var a="3.14159";

var a2=Number(a);//结果为3.14159

2.参数为数值

var b=3.14159

var b2=Number(b);//结果为3.14159

2.8.parseInt()与parseFloat()

1.parseInt()

parseInt() 函数可解析一个字符串,并返回一个整数。开头和结尾的空格是允许的。如果参数是一个数字,那么该方法将去掉小数部分,并且返回整数部分。

例如:

parseInt(3.14159);//3  参数为数值
parseInt("3.14159");//3   参数为字符串

2.parseFloat()

函数可解析一个字符串,并返回一个浮点数。参数可以为数字,如果参数为小数数字,返回小数数字,如果为整数数字,返回整数数字

例如:

parseFloat(3.14159)//3.14159
parseFloat("3.14159")//3.14159
parseFloat(5)//5
parseFloat("5");//5

2.9.string() — 与toString()同

把不同的对象转换为字符串:

<script>

var test1 = new Boolean(1);
var test2 = new Boolean(0);
var test3 = new Boolean(true);
var test4 = new Boolean(false);
var test5 = new Date();
var test6 = new String("999 888");
var test7 = 12345;

document.write(String(test1)+ "<br>");
document.write(String(test2)+ "<br>");
document.write(String(test3)+ "<br>");
document.write(String(test4)+ "<br>");
document.write(String(test5)+ "<br>");
document.write(String(test6)+ "<br>");
document.write(String(test7)+ "<br>");

</script>

以上实例输出结果:

true
false
true
false
Fri Aug 27 2021 16:31:26 GMT+0800 (中国标准时间)
999 888
12345

2.10.unescape()

功能描述:可对通过 escape() 编码的字符串进行解码。该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),
用 Unicode 字符 \\u00xx 和 \\uxxxx 替换这样的字符序列进行解码。
温馨提示:ECMAScript v3 已从标准中删除了 unescape() 函数,并反对使用它,因此应该用 decodeURI() 和 decodeURIComponent() 取而代之。

示例:

var str="Need tips? Visit RUNOOB!";
var str_esc=escape(str);
document.write(str_esc + <

以上是关于JavaScript之全局函数详解的主要内容,如果未能解决你的问题,请参考以下文章

JQuery之each函数详解

Jquery之each函数详解

Javascript闭包(Closure)详解

Js_闭包详解

常用Javascript代码片段集锦

JavaScript 变量作用域 详解