本内容是《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](https://img-blog.csdnimg.cn/img_convert/1dbe443a91ccca737ecca7354c295d4f.png)
Web前端开发之Javascript-零点程序员-王唯