一、 全局对象
ECMAScript把全局对象称为global,但浏览器中将window作为全局对象,window的属性就是全局变量。
全局变量分两种,一种是ECMAScript标准规定的:
- global.parseInt
- global.parseFloat
- global.Number
- global.String
-global.Boolean
- global.Object
- ...
另一种是浏览器私有的:
- window.alert
- window.prompt
- window.comfirm
- window.console.log
- window.console.dir
- window.document
- window.document.createElement
- window.document.getElementById
- ...
这里主要介绍 ECMAScript 标准中的全局变量
二、 全局函数
JS 中常见的全局函数有Number、String、Boolean、Object等(实际是window.Number,在使用全局属性时,前面的window或global可以省略)
声明一个对象又两种方法,以Number为例:
var n = 1
var n = new Number(1)
在使用 var n = new Number() 声明一个Number对象时,n会具有一些属性和方法,如
var n1 = new Number(1) //声明Number对象n1
n1.toString() //'1'
n1.valueOf() //1
需要注意的是,在JS中,即使只是声明了一个number类型的量,也可以直接使用Number对象的方法。
var n2 = 1
n2.toString() //'1'
n2.valueOf() //1
实际上,在对基本类型类型 n2 使用 toString 方法时,JS引擎会生成一个临时的 Number 对象 temp 在调用 n2.toString() 时,实际上是在调用 temp.toString() ,并将 temp.toString() 的返回值作为 n2.toString() 的返回值。
n2.toString()
/*实际运行的情况是
var temp = new Number(n2)
n2.toString() = temp.toString() //'1'
*/
需要注意的是,在上述过程执行完毕以后,temp 会被回收
var n = 1
n.xxx = 3
n.xxx //undefined
同样的,Number、String、Boolean等全局函数也可以这样声明
var s1 = 'Hello'
var s2 = 'World'
s1.concat(s2) //'HelloWorld'
s1.charAt(4) //o(获取s1的第4+1个字符)
s2.charCodeAt(3) //108(获取s2的第3+1个字符的Unicode编码)
s1.slice(0, 2) //He
s2.slice(2, 5) //rld
s1.replacae('e', 'o') //hollo(得到一个新字符串,但s1还是hello)
' username '.trim() //username
var f = false
var f2 = new Boolean(false)
if(f){console.log(1)}
if(f2){console.log(2)} //2
var o1 = {}
var o2 = new Object()
/*****
o1和o2没区别但是
o1 === o2 //false
*****/
三、 原型与原型链
声明一个全局函数时会创建一个相应的对象实例,每个对象都有相应的属性和方法,但有一些属性和方法是所有对象都有的,即公有属性。如果每创建一个对象,都把这些共有的方法都创建一遍,就会造成内存浪费。
从上面打出来的结果可以看到:
- n1有一个
__proto__属性(基本类型Number的公有属性) n1.__proto__有很多属性,包括toFixed、toExponential等n1.__proto__中还有一个__proto__属性,包括valueOf、toString、constructor等与object.__proto__相同,这是因为object.__proto__就是所有对象的公有属性。obj.__proto__实际上有一个叫做__proto__的属性(console.log 没有显示),值为null
当我们读取某个属性时,JS引擎先在自身属性中查找,找到返回,如果没有,再在__proto__中积雪查找,直到查找到或者__proto__为null,整个过程中__proto__是一层嵌套一层,呈一种链式结构,称为原型链。
在JS中,每个函数都有一个特殊的属性叫作原型(prototype),指向每类函数的公有属性,保证了共有属性的存在性。因为JS中没有被引用的对象,会被当做垃圾回收掉,所以还需要有一个变量去引用它,才能保证随时可以调用这些共有属性。同时也解决了内存浪费的问题。
prototype与__proto__的关系是:
var 对象 = new 函数()
对象.__proto__ === 对象的构造函数.prototype
所以
var number = new Number()
number.__proto__ === Number.prototype
var object = new Object()
object.__proto__ === Object.prototype
var function = new Function()
function.__proto__ === Function.prototype
所有函数都是由 Function 构造出来的(包括 Function 类型),所以
Number.__proto__ === Function.prototype //ture
Object.__proto__ === Function.prototype //ture
Function.__proto__ === Function.prototye //ture