javascript 本地对象和内置对象_第17节 Javascript内置对象Global全局及Math对象-Web前端开发

本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。

ECMAScript对内置对象的定义是:“由ECMAScript实现提供的,不依赖于宿主环境的对象,这些对象在ECMAscript程序执行之前就已经存在了”;说明不必显式地实例化内置对象,因为它们已经实例化了;之前介绍的Object、Array和String等都是内置对象。

另外还提供了两个内置对象:Global和Math。

Global对象:

Global对象可以说是ECMAScript中最特别的一个对象了,是JS中最特殊的对象;

全局对象及其属性在任何地方都可以直接使用;

Global对象是对象,不是类,所以没有构造函数,不能new实例化;

这个对象是不存在的,换句话说,不属于任何其他对象的属性和方法,最终都是它的属性和方法; 因此它没有名字(Global不是全局对象的名字,只是我们这样称呼它)。

全局对象是一个预定义对象,用作Javascript中全局属性和全局函数的占位符;通过全局对象,可以访问所有其他预定义的对象、函数和属性;

注:所有全局变量也都是全局对象的属性;

全局属性:

Global对象的一些属性,其中一部分属性前面的课程已经讲过,如undefined、NaN以及Infinity都是Global属性;

ECMAScript5禁止给undefined、NaN和Infinity赋值,这样做即使在非严格模式下也会导致错误。

全局对象:Math、JSON;

全局函数:

isNaN()、isFinite()、parseInt()、parseFloat()、eval();

isNaN()用来确定一个值是否为NaN,而Number.isNaN()确定传递的值是否为NaN和其类型是Number;它是原始的全局isNaN的强大的版本;如:

console.log(isNaN("w"));    // trueconsole.log(Number.isNaN("w"));  // false

Number.isNaN()和isNaN()相比,前者不会强制将参数转换成数字,只有该参数是真正的数字类型,且值为NaN的时候才会返回true。

console.log(isNaN(NaN)); // trueconsole.log(Number.isNaN(NaN)); // trueconsole.log(isNaN(37)); // falseconsole.log(Number.isNaN(37)); // falseconsole.log(Number.isNaN('37')); // falseconsole.log(isNaN('37')); // falseconsole.log(Number.isNaN(undefined)); // falseconsole.log(isNaN(undefined)); // trueconsole.log(Number(undefined)); // NaNconsole.log(Number.isNaN({})); // falseconsole.log(isNaN({})); // trueconsole.log(Number({})); // NaNconsole.log(Number.isNaN('37,5')); // falseconsole.log(isNaN('37,5')); // trueconsole.log(Number('37,5')); // NaNconsole.log(Number.isNaN('123ABC')); // falseconsole.log(isNaN('123ABC')); // trueconsole.log(Number('123ABC')); // NaNconsole.log(Number.isNaN(true)); // falseconsole.log(isNaN(true)); // falseconsole.log(Number(true)); // 1console.log(Number.isNaN(null)); // falseconsole.log(isNaN(null)); // falseconsole.log(Number(null)); // 0console.log(Number.isNaN('')); // falseconsole.log(isNaN('')); // falseconsole.log(Number('')); // 0console.log(Number.isNaN(' ')); // falseconsole.log(isNaN(' ')); // falseconsole.log(Number(' ')); // 0console.log(Number.isNaN(new Date())) // falseconsole.log(isNaN(new Date())); // falseconsole.log(Number(new Date())); // 1558496426074console.log(Number.isNaN(new Date().toString())); // falseconsole.log(isNaN(new Date().toString())); // trueconsole.log(Number(new Date().toString())); // NaN

只要不是NaN任何值放入Number.isNaN()都会返回false。对于isNaN()能被Number()转换成数字的或本身就是数字返回false,不能转为数字的会返回true。(即:如果忽略掉能被转成数字的字符串,所有数字对于isNaN()都返回false,非数字都返回true);

Number.isFinite()和全局的isFinite()相比,不会强制将一个非数值的参数转换成数值,这就意味着,只有数值类型的值,且是有穷的,才返回true;

  console.log(Number.isFinite(Infinity)); // false  console.log(isFinite(Infinity)); // false  console.log(Number.isFinite(NaN)); // false  console.log(isFinite(NaN)); // false  console.log(Number.isFinite(2e64)); // true  console.log(isFinite(2e64)); // true  console.log(Number.isFinite('0')); // false  console.log(isFinite('0')); // true  console.log(Number.isFinite(undefined)); // false  console.log(isFinite(undefined)); // false  console.log(Number(undefined)); // NaN  console.log(Number.isFinite(null)); // false  console.log(isFinite(null)); // true  console.log(Number(null)); // 0

只有为Number的值且是有限的时候Numebr.isFinite()会返回true。而isFinite()在参数经过Number转换后再判断是否是有限的。正无穷、负无穷和NaN都不是有限数字。

Number.isInteger()用来判断给定的参数是否为整数;只有是Number类型的值并且是整数才会返回true,Infinity和NaN都不是整数。

全局构造函数:全局对象还定义了一些属性,用来引用Javascript预定义的所有其他对象,这些对象大部分是原生引用类型的构造函数:

Object、Number、String、Boolean、Array、Date、Function、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。

根据JavaScript的运行环境,在JS中存在两种全局对象:JS全局对象和window全局对象;

当Javascript放在特定宿主环境时,全局对象通常具有与该特定环境相关的额外属性;这些额外属性并不是ES标准规定的,而是由宿主环境实现的;如在客户端Javascript中,全局对象是Window对象,表示运行JS的Web浏览器窗口;或在nodejs中,Global指的就是global对象;

var str = "zeronetwork";console.log(window.str);

全局中的this:由于全局对象位于作用域链的最顶部,所以在全局环境中,关键字this指的就是全局对象;如果在是浏览器中,this指的就是window对象;

console.log(this);

在ES中,全局对象的预定义属性都是不可枚举的,因此使用for/in来只能列出所有隐式或显式声明的全局变量,如:

for(var name in this)  // this或者window    console.log(name);

全局变量:

所有的全局变量都全局对象的属性;

声明的4种方法:

  • 1.直接在全局作用域中用var 声明的变量就是全局变量,此种方式声明的变量具有不可配置的属性,不能使用delete操作符把变量删除。
  • 2.window.变量,这种声明的变量也是全局变量,但这种变量跟上面用var 声明的变量有点不一样,这种方式声明的全局变量是可配置的,因此能用delete操作符把变量删除。
  • 3.隐式声明全局变量,就是不使用var声明,直接进行赋值的变量,在不严格模式中,相当于window.变量这种方式,但在严格模式下,会报错。
  • 4.在html中给标签指定一个id属性,也相当于给Window对象添加了一个id的属性,在javascript中可直接通过标签的id访问该标签(或者window['id'])。

Global对象方法:

1)字符串编码方法:

escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串(其中某些字符被替换成了十六进制的转义序列 )。注:该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: - _ . ! ~ * ‘ ( ) 。其他所有的字符都会被转义序列替换。

unescape() 函数可对通过 escape() 编码的字符串进行解码。 注:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 甥〰硸 和 甥硸硸 替换这样的字符序列进行解码。

2)URI编码方法:

Global对象的encodeURI()和encodeURIComponent()可把字符串作为 URI(Uniform Resource Identifiers,通用资源标识符)进行编码,以便发送给浏览器;有效的URI中不能包含某些字符,如空格;这两个编码方法,用特殊的UTF-8编码替换所有无效的字符,从而让浏览器能够接受和理解。

注:两个方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ‘ ( ),encodeURI()也不会对在URI中具有特殊含义的符号;/?:@&=+$,#进行转义,但encodeURIComponent()会;

其中,encodeURI()主要用于整个URI,如:http://www.zeronetwork.cn/my case.html,而encodeURIComponent()主要用于对URI中的某一段,如my case.html进行编码;

它们的主要区别在于,encodeURI()不会对本身属于URI的特殊字符进行编码,如:冒号、正斜杠、问号和井号;而encodeURIComponent()则会对它发现的任何非标准字符进行编码,如:

var url = "http://www.zeronetwork.cn/my case.html#start";console.log(encodeURI(url));  // http://www.zeronetwork.cn/my%20case.html#startconsole.log(encodeURIComponent(url));  // http%3A%2F%2Fwww.zeronetwork.cn%2Fmy%20case.html%23startconsole.log(encodeURI("零点程序员 王唯"));console.log(encodeURIComponent("零点程序员 王唯"));console.log(encodeURI(";/?:@&=+$#"));console.log(encodeURIComponent(";/?:@&=+$#"));

注:一般来说,使用encodeURIComponent()的场景比使用encodeURI()要多,因为在实践中更常见的是对查询字符串参数而不是对基础URI进行编码;

与encodeURI()和encodeURIComponent()方法对应的两个方法,分别是decodeURI()和decodeURIComponent();其中decodeURI() 只能对 encodeURI() 编码过的 URI 进行解码;如:可将%20替换成一个空格,但不会对%23作任何处理,因为%23代表井号,而井号不是使用encodeURI()替换的;同样的,decodeURIComponent()能够解码encodeuricomponent()编码的所有字符,即它可以解码任何特殊字符的编码,如:

var uri = "http%3A%2F%2Fwww.zeronetwork.cn%2Fmy%20case.html%23start";alert(decodeURI(uri));alert(decodeURIComponent(uri));

注:URI方法代替了已经被ECMA-262第3版废弃的escape和unescape()方法,因为URI方法能对所有Unicode编码,而原来的方法只能对ASCII符号正确编码;因此在实际场景中,一定要使用URI方便,不要再使用escape()和unescape()方法;

console.log(escape("Visit https://www.zeronetwork.cn"));console.log(escape("?!=()#%&"));console.log(escape("https://www.zeronetwrok.cn/index.html"));console.log(escape("https://www.zeronetwrok.cn/index.html?id=001&username=王唯"));console.log(encodeURI("Visit https://www.zeronetwork.cn"));console.log(encodeURI("?!=()#%&"));console.log(encodeURI("https://www.zeronetwrok.cn/index.html"));console.log(encodeURI("https://www.zeronetwrok.cn/index.html?id=001&username=王唯"));console.log(encodeURIComponent("Visit https://www.zeronetwork.cn"));console.log(encodeURIComponent("?!=()#%&"));console.log(encodeURIComponent("https://www.zeronetwrok.cn/index.html"));console.log(encodeURIComponent("https://www.zeronetwrok.cn/index.html?id=001&username=王唯"));

eval() 方法:

是ECMAScript中最强大的一个方法,其就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMASCript或JavaScript字符串, 并返回值;如:

eval("alert('hi')");  // 等价于以下alert("hei");document.write(eval("2+2"));

说明:当解析器发现eval()方法时,它会将传入的参数当作实际的ECMAScript语句来解析,然后把执行结果插入到原位置;

如果解析失败,会抛出异常。

通过eval()执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的作用域链;这意味着通过eval()执行的代码可以引用在包含环境中定义的变量,如:

var msg = "hello world";eval("alert(msg)");function swapImg(){    var img = prompt("请输入要改变图片的名字","");    var imgObj = eval("document.getElementById(img)");    imgObj.src = "images/1.jpg";}window.onload = swapImg();

同样的,也可以在eval()中定义一个函数,在该调用的外部代码中引用这个函数,如:

eval("function sayHi(){alert('Hi');}");sayHi();

说明:函数sayHi()虽然是在eval()内部定义,但由于对eval()的调用最终会被替换成定义函数的实际代码;其对于定义变量也一样,如:

eval("var msg='hello world';");alert(msg);

注:在eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包含在一个字符串中,它们只在eval()执行的时候被创建;

eval() 当在函数内部作用域中,eval执行的是局部,如果调用window.eval则在全局空间执行,如:

var s = "global";function func(){eval("var s = 'local';");window.eval("var s = 'local';");  // 全局}func();alert(s);

eval()具有更改局部变量的能力;

var geval = eval;var x = "global", y = "global";function f(){    var x = "local";    eval("x += ' changed';");    return x;}function g(){    var y = "local";    geval("y += ',changed';");    return y;}console.log(f(), x);console.log(g(), y);

注:在严格模式下,ES5对eval()的行为施加了更多的限制,在外部访问不到eval()中创建的任何变量或函数,同时,为eval()赋值也会导致错误,如:

"use strict";var x = 5;eval("var y=8;alert(y);"); // 内部可以访问xconsole.log(y);  // 抛出异常,不能访问

总结:能够解释代码字符串的能力非常强大,但也非常危险;因此在使用eval()时必须极为谨慎,特别是在用它执行用户输入数据的情况下;否则,可能会有恶意用户输入威胁站点或应用程序的代码,即所谓的代码注入。

window对象:

ECMAScript虽然没有指出如何直接访问Global对象,但Web浏览器都是将这个全局对象作为window对象的一部分加以实现的;因此,在全局作用域中声明的所有变量和函数,就都成为了window对象的属性,如:

var color="red";function sayColor(){    alert(window.color);}window.sayColor(); // red

注:JavaScript中的window对象除了扮演ECMAScript规定的Global对象的角色外,还承担了很多别的任务(即window对象下的一些方法和属性都是js原生提供的,但在浏览器环境中,大量的功能都是由宿主对象完成的);

另外一种取得Global对象的方法,如:

var global = function(){    return this;}();

说明分析:以上代码创建了一个立即调用的函数表达式,返回this;在没有给函数明确指定this值的情况下,this值等于Global对象。

Math对象:

JS自身定义了很多数字运算的方法被定义在Math对象中;与在Javascript中直接编写的计算功能相比,Math对象提供的计算功能执行起来要快得多。

Math对象是一个静态对象,或者称为工具类,不能使用new关键字创建对象,应直接使用”对象名.成员”的格式来访问其属性和方法,如: var num=Math.random();

1)Math对象属性:

Math对象包含的属性大都是数学计算中可能会用到的一些特殊值,如:

  • E:自然对数的底数,即常数e.约等于2.718;
  • LN10:代表10的自然对数,约等于2.302;
  • LN2:代表2的自然对象,约等于0.693;
  • LOG2E:代表以2为底E的对数;
  • LOG10E:代表以10为底E的对数;
  • PI:代表II的值,约等于3.1415926;
  • SQRT1_2:代表2的平方根分之一,约等于0.707;
  • SQRT2:代表2的平方根,约等于1.414;

2)Math对象方法:

Math对象还包含许多方法,用于辅助完成简单和复杂的数学计算;

min()和max()方法:用于确定一组数值中的最小值和最大值;这两个方法都可以接收任意多个数值参数,如:

var max = Math.max(3,54,32,17);var min = Math.min(3,54,32,17);alert(max);alert(min);

要找到数组中的最大或最小值,可以使用apply()的方法,如:

var arr = [1,23,45,67,77,2,88,2];var max = Math.max.apply(Math, arr);alert(max);

ceil:向上舍入,返回大于参数值的最小整数(天花板值)

floor:向下舍入,返回小于参数值的最大整数(地板值)

round:标准舍入,即四舍五入法;

以上三个方法都是小数值舍入为整数的方法;如:

alert(Math.ceil(25.9));alert(Math.ceil(25.5));alert(Math.ceil(25.1));alert(Math.round(25.9));alert(Math.round(25.5));alert(Math.round(25.1));alert(Math.floor(25.9));alert(Math.floor(25.5));alert(Math.floor(25.1));

如果只是想取整,即想舍弃掉小数部分,但参数有可能是正值也有可能是负值,以上方法都不合适;解决方案:如果是正值,使用floor,如果是负值,使用ceil,封装一个函数,如:

function toInteger(x){    x = Number(x);    return x 

注:当然使用parseInt()也可以达到这样的效果。

当在round()中使用负数时,如:

console.log(Math.round(-1.1));  // -1console.log(Math.round(-1.5));  // -1console.log(Math.round(-1.6));  // -2

如果按照正数的逻辑,当四舍时,结果值应小于参数,当五入时,结果值应大小参数,但为负数时正相反;

random()方法:

返回介于0和1之间的随机数(包括0和不包括1),在一些应用场景中,非常有用,因为可以利用它来随机显示一些内容;

一般与其他方法配合使用,以求得一个在一个范围内的随机数,如:

值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值);

说明:因为Math.random()总是返回一个小数值,用这个值乘以一个整数,再加上一个整数,结果还是小数,因此使用floor取整。如:取得1到10之间的数值,如:

var num = Math.floor(Math.random() * 10 +1);alert(num);

而如果想要一个介于2到10之间的值,如:

var num = Math.floor(Math.random() * 9 + 2);

也可以按这样的规则:number=Math.floor(Math.random() * (最大数 - 最小数 + 1) + 最小数);

多数情况下,可以封装成一个函数来计算可能值的总数和第一个可能的值,如:

function intRadom(min,max){    var choices = max - min + 1;    return Math.floor(Math.random() * choices + min);}var num = intRadom(2,10);console.log(num);说明分析;利用这个函数,可以方便地从数组中随机取出一项,如:var colors = ["red","green","blue","yellow","black"];var color = colors[selectFrom(0,colors.length-1)];alert(color);

随机返回字符,如:

function getRandomString(len){    var alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';    alpha += 'abcdefghijklmnopqrstuvwxyz';    alpha += '0123456789-_';    var str = '';    for(var i=0; i

可换成中文:alpha = '让我掉下眼泪的不止昨夜的酒让我依依不舍的';

function getRandomHan(len){    var str = '';    for(var i=0;i

Math对象中还包含其他一些完成各种简单或复杂计算有关的方法:

abs(num):绝对值、asin(x):反正弦值、exp(num):Math.E的num次幂、atan(x):反正切值、log(num):num的自然对数、atan2(y,x):y/x的反正切值、pow(num,power):num的power次幂、cos(x):余弦值、sqrt(num):平方根、sin(x):正弦值、acos(x):反余弦值、tan(x):正切值

注:虽然ECMA-262规定了这些方法,但不同实现可能会对这些方法采用不同的算法,毕竟,计算某个值的正弦、余弦和正切的方式多种多样;也正因为如此,这些方法在不同的实现中可能会有不同的精度。

1dbe443a91ccca737ecca7354c295d4f.png

Web前端开发之Javascript-零点程序员-王唯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值