原生JS:全局属性、全局方法详解

全局属性、全局方法

原创文章,转摘请注明出处:苏福:http://www.cnblogs.com/susufufu/p/5853342.html

首先普及几个我总结的非常实用又很基础的知识:(呵呵,仅仅是学习权威指南的笔记而已)

typeof 返回的是字符串,有8种可能:"number"、"string"、"boolean"、"object"、"function"、"undefined"、"symbol"(ES6)、宿主对象类型

假值:false、 null、 undefined、 0 、-0 、NaN、""

真值:除了以上的值,其他值均为真值;

对象:除了字符串字面量、数字字面量、true、false、null、undefined之外,其他值都是对象!

数字a 转 字符串:

  • a.toString(n) //n表示进制
  • a.toFixed(i)   a.toPrecision(j)  //i为小数位数,j为要显示位数
  • a.toExponential(i) //科学计数形式

字符串s 转数字:转换失败返回NaN,忽略前置的空格,尽可能多的转换数字,忽略后面的非数字内容,其中'0X'、'0x'开头的则把它当着16进制数来转换

  • parseInt(s,n) //n表示进制,可选参数,把s当着n进制数来转为十进制数
  • parseFloat(s) //转为浮点数
正题开始:(以下是本人一边翻书,一边查MDN,一边 baidu,权衡之后得到的总结)

表示一个简单的值的全局属性:

Infinity 

一个数值,表示无穷大,有Infinity和-Infinity

  • Infinity 的初始值是 Number.POSITIVE_INFINITY
  • 用0作除数会产生Infinity
  • 比无穷大还大的值仍然是无穷大
  • Infinity(正无穷大)大于任何值。该值和数学意义上的无穷大很像,例如任何正值乘以 Infinity 结果为 Infinity, 任何数值(除了Infinity 和 -Infinity)除以 Infinity 为 0。
  • NaN 属性是一个不可配置(non-configurable)、不可枚举、不可写(non-writable)的属性,所以无法使用 for/in 循环来枚举 NaN 属性,也不能用 delete 运算符来删除它。

NaN

表示 Not-A-Number 的值。NaN 属性的初始值就是 NaN,和 Number.NaN 的值一样。

  • 在现代浏览器中(ES5中), NaN 属性是一个不可配置(non-configurable)、不可枚举、不可写(non-writable)的属性,所以无法使用 for/in 循环来枚举 NaN 属性,也不能用 delete 运算符来删除它。
  • 但在ES3中,这个属性的值是可以被更改的,但是也应该避免覆盖。
  • 等号运算符(== 和 ===) 不能被用来判断一个值是否是 NaN。必须使用 Number.isNaN() 或 isNaN() 函数。
  • NaN 与所有值都不相等,包括它自己(在JavaScript中唯一一个不等于自己的值)NaN === NaN;        // false
  • NaN是一个数字,类型为number :typeof NaN  //number 
  • NaN转为数字为NaN,转为布尔值为false
  • 0 除以0会返回NaN ,但是其他数除以0则不会返回NaN,而是Infinity。

undefined

在JavaScript中,undefined这个词有多重含义。undefined是全局对象的一个属性

  • 一个未初始化的变量的值为undefined,一个没有传入实参的形参变量的值为undefined,如果一个函数什么都不返回,则该函数默认返回undefined.
  • 首字母大写的Undefined表示的是一种数据类型,小写的undefined表示的是属于这种数据类型的唯一的一个值.
  • 在JavaScript代码中,你看到的undefined最有可能是全局对象的一个属性,该属性的初始值是就是前面所说的原始值undefined,还有种情况就是,这个undefined是个局部变量,就像其他普通变量一样,没有任何特殊性,它的值不一定是undefined,但通常情况下都是的.下面我们所说的undefined,都指的是window.undefined这个属性.
  • 在ES5中,window.undefined成了一个不可写,不可配置的数据属性,它的值永远是undefined,但是undefined这个词不是保留字,可以被重新声明并赋值,所以直接使用undefined是不保险的,可以用void 0来获得一个纯正的undefined。
  • 必须使用严格相等运算符===来判断一个值是否是undefined,而不能使用普通的相等运算符==,因为在JavaScript中null == undefined是返回true的
  • 如果一个变量根本没有被声明,只有使用typeof判断才不会报错typeof x === 'undefined'。用相等运算符判断会抛出异常。(对已声明但未初始化的和未声明的变量执行typeof,都返回"undefined"。)
  • undefined转为数字为NaN,转为布尔值为false
null 

null 是一个javascript字面量,表示空值,它是javascript原始值之一。

  • null 常被放在期望一个对象,但是不引用任何对象的参数位置,null表示一个空对象指针,typeof操作会返回"object"。
  • 在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是0。由于 null 代表的是空指针(大多数平台下值为0x00),因此,null的类型标签也成为了0,typeof null就错误的返回了"object".
  • null转为数字为0,转为布尔值为false 

null 与 undefined 的区别:null是字面量,undefined是全局对象的属性

  • typeof null        // object 
  • typeof undefined   // undefined
  • null === undefined // false
  • null  == undefined // true(null会执行类型转换) 

null与空对象{}的区别:个人理解为null未被分配内存,而{}分配了内存,只是值为空

var a = {};  

var b = null;

a.name = 'realwall';

b.name = 'jim'//这里会报错,b为空指针对象,不能像普通对象一样直接添加属性。

 

执行特定功能并返回结果的全局方法:

eval(string)

eval()是一个顶级函数并且跟任何对象无关。

  • eval()的参数是一个字符串。如果字符串表示了一个表达式,eval()会对表达式求值。如果参数表示了一个或多个JavaScript声明, 那么eval()会执行声明。不要调用eval()来为算数表达式求值; JavaScript 会自动为算数表达式求值。
  • 如果要将算数表达式构造成为一个字符串,你可以用eval()在随后对其求值
  • 如果参数不是原始字符串,eval()将会将参数原封不动的返回。
  •  eval()只能直接调用,不可以间接调用,如使用变量来引用eval(),然后调用它。那么可能会发生运行时错误

  •  eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。当Function , setInterval 和 setTimeout这几个方法接收一个字符串作为参数时,内部调用了eval()方法

  •  eval通常用在一些需要动态执行字符串,或将字符串转为javascript对象的场景,比如将json字符串转为javascript对象。

  •  eval()函数并不会创建一个新的作用域,并且它的作用域就是它所在的作用域。可以用window.eval()的方式来把它的作用域变为全局(兼容IE8的对应方法为window.execScript)

  • 避免在不必要的情况下使用eval:eval() 是一个危险的函数, 它可以像拥有调用者的权力一样调用代码。如果你使用了字符串来运行eval(),那么你的代码可能被恶意方(不怀好意的人)影响, 通过在使用方的机器上使用恶意代码,可能让你失去在网页或者扩展程序上的权限。eval() 可读性差、不方便优化和调试、有性能消耗。在任何实用eval()的地方,基本都可以有一般的替代方案 

isFinite(testValue)

它是全局方法,不与任何对象有关系。你可以用这个方法来判定一个数字是否是有限数字。isFinite 方法检测它参数的数值。他会首先尝试将参数转换为一个数值,如果参数是 NaN、Infinity、-Infinity,则返回false,其他返回 true

isNaN(testValue)

用来判断一个值是否为 NaN。注:isNaN函数包含一些非常有意思的强制转换规则;你也可以通过 ECMAScript 6 中定义的 Number.isNaN() 或者 typeof 来判断一个值是否为非数值

  • 如果isNaN函数的参数不是Number类型, isNaN()会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是NaN进行判断(空字符串和布尔值会被强制转换为数值0或1,对它们isNaN返回false)而isNaN(undefined)返回true
  • ECMAScript (ES6)包含了Number.isNaN()函数。通过Number.isNaN(x)来检测变量x是否是一个非数值将会是一种可靠的做法。然而,在缺少Number.isNaN函数的情况下, 通过表达式(x != x) 来检测变量x是否是NaN会更加可靠。
parseFloat(string)

将参数中指定的字符串解析成为一个浮点数字并返回.parseFloat是个全局函数,不属于任何对象.

  • 参数字符串前置的空白符会被忽略。
  • 它会正确解析:正负号(+或-),数字(0-9),小数点,或者科学记数法中的指数(e或E),当它遇到其它字符时,会忽略之后的所有字符,并立即返回结果
  • 如果参数字符串的第一个字符不能被解析成为数字,则parseFloat返回NaN
  • 最好通过调用isNaN函数来判断parseFloat的返回结果是否是NaN。如果让NaN作为了任意数学运算的操作数,则运算结果必定也是NaN.
  • parseFloat 也可转换和返回Infinity值. 可以使用isFinite 函数来判断结果是否是一个优先的数值 (非Infinity, -Infinity, 或 NaN).
  • 该函数通过正则表达式的方式,在需要更严格地转换float值时可能会有用: (只接受纯数字值)

var filterFloat = function (value) {
if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)){
return Number(value);
   }
 return NaN;
}
 
parseInt(string, radix)

将给定的字符串以指定基数(radix/base)解析成为整数。radix是一个2到36之间的整数值,用于指定转换中采用的基数。比如参数"10"表示使用我们通常使用的十进制数值系统。总是指定该参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当忽略该参数时,不同的实现环境可能产生不同的结果。

  • parseInt 函数将第一个参数(字符串)解析并试图返回一个整数或者NaN(Not a Number)。如果第一个字符不能被转换成数字,parseInt返回NaN。如果结果不是NaN,那么返回值是把第一个参数看作是radix参数指定的进制下的数,然后把它转换成十进制的整数
  • 如果 parseInt 遇到了不属于radix参数所指定的基数中的字符,那么该字符和其后的字符都将被忽略。接着返回已经解析的整数部分。parseInt 将截取整数部分。开头和结尾的空白符允许存在,会被忽略。
parseInt("10546", 2); //2
parseInt("546", 2); //NaN
parseInt("FXX123", 16); //15
parseInt("12",13); //15
parseInt(" -17", 8); //-15
parseInt("0x11", 16); //17
parseInt("0x11", 0); //17
parseInt("0x11"); //17

在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理:

  • 如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
  • 如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript 5 规范不再允许parseInt函数的实现环境把以0字符开始的字符串作为八进制数值,ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值
  • 如果字符串 string 以其它任何值开头,则基数是10 (十进制)。

一个更严格的方法来解析整型值:(任何不具有实际意义数字值的值均返回NaN)

filterInt = function (value) {
if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value)){
return Number(value);
 }
return NaN;
}
filterInt('421op'); //NaN

 

encodeURI(URI)

对统一资源标识符(URI)进行编码的方法。它使用1到4个转义序列来表示每个字符的UTF-8编码(只有由两个代理字符区组成的字符才用四个转义字符编码)。参数URI是一个完整的URI.

  • 假定一个URI是完整的URI,那么无需对那些保留的并且在URI中有特殊意思的字符进行编码。
  • encodeURI 会替换除以下字符之外的所有字符,即使它们具有适当的UTF-8转义序列:

类型

包含

保留字符

; , / ? : @ & = + $

非转义的字符

字母 数字 - _ . ! ~ * ' ( )

数字符号

#

  • 请注意,encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 "&", "+", 和 "=" 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而encodeURIComponent这个方法会对这些字符编码。
  • 另外,如果试图编码一个非高-低位完整的代理字符,将会抛出一个 URIError 错误,例如:
// 编码高-低位完整字符
console.log(encodeURI('\uD800\uDFFF'));
// 编码单独的高位字符抛出 "Uncaught URIError: URI malformed"
console.log(encodeURI('\uD800'));
// 编码单独的低位字符抛出 "Uncaught URIError: URI malformed"
console.log(encodeURI('\uDFFF'));
  • 并且需要注意,如果URL需要遵循较新的RFC3986标准,那么方括号是被保留的(给IPv6),因此对于那些没有被编码的URL部分(例如主机),可以使用下面的代码:
function fixedEncodeURI (str) {
  return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
}
 

是对统一资源标识符(URI)的组成部分进行编码的方法。它使用一到四个转义序列来表示字符串中的每个字符的UTF-8编码(只有由两个Unicode代理区字符组成的字符才用四个转义字符编码)。参数str是String. URI 的组成部分。

  • 它转义除了字母、数字、().!~*'-_之外的所有字符。
  • 注意,如果试图编码一个非高-低位完整的代理字符,将会抛出一个 URIError 错误
  • 为了避免服务器收到不可预知的请求,对任何用户输入的作为URI部分的内容你都需要用encodeURIComponent进行转义。比如,一个用户可能会输入"Thyme &time=again"作为comment变量的一部分。如果不使用encodeURIComponent对此内容进行转义,服务器得到的将是comment=Thyme%20&time=again。请注意,"&"符号和"="符号产生了一个新的键值对,所以服务器得到两个键值对(一个键值对是comment=Thyme,另一个则是time=again),而不是一个键值对。
  • 对于 application/x-www-form-urlencoded (POST) 这种数据方式,空格需要被替换成 '+',所以通常使用encodeURIComponent 的时候还会把 "%20" 替换为 "+"。
  • 为了更严格的遵循 RFC 3986(它保留 !, ', (, ), 和 *),即使这些字符并没有正式划定 URI 的用途,下面这种方式是比较安全的:

function fixedEncodeURIComponent (str) {
    return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
 
decodeURI(encodedURI)

用于解码由 encodeURI 方法或者其它类似方法编码的统一资源标识符(URI)。将已编码 URI 中所有能识别的转义序列转换成原字符,但不能解码那些不会被 encodeURI 编码的内容(例如 "#")

 decodeURI("https://developer.mozilla.org/ru/docs/JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
// "https://developer.mozilla.org/ru/docs/JavaScript_шеллы"
 
decodeURIComponent(encodedURI)

用于解码由 encodeURIComponent 方法或者其它类似方法编码的部分统一资源标识符(URI)。参数encodedURI 是编码后的部分 URI


escape() 已被废弃
unescape()  已被废弃

 

 

 

posted on 2016-09-08 15:50  SuriFuture  阅读(9649)  评论(1编辑  收藏  举报

导航