JS原型与原型链
一. 全局对象window
ECMAScript 规定全局对象叫做 global,但是浏览器把 window 作为全局对象(浏览器先存在的)
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
window对象中的所有方法都可以省去window,window.alert可以写成alert,且这些属性在不同浏览器中显示出来的效果也可能不同
二. 简单类型与对象的区别
var n1 = 1
var n2 = new Number(1)
以上两种都是声明数值的方法,第一种创建的是简单数据类型,第二种创建的是一个对象。他们之间有什么区别呢?
首先是占用内存的方式不一样,
内存图
由于n1是简单数据类型,存储在栈内存中,而n2是一个对象,所以栈内存存储的是一个地址,地址指向该对象内容所存储的堆内存。
三. 一些常用的属性
- Number对象
Number的常用属性 | 含义 |
---|---|
Number.valueOf() | 获取对象本身的值 |
Number.toString() | 将数值转化为字符串 |
Number.toFixed() | 将其转换为小数 |
Number.toExponential() | 将其转化为科学计数法 |
- String对象
String的常用属性 | 含义 |
---|---|
String.charAt() | 获取字符串中某一位的字符 |
String.charCodeAt() | 获取字符串中某一位的字符的Unicode编码 |
String.trim() | 删除字符串中多余的空格 |
String1.concat(String2) | 连接字符串1和字符串2 |
String.slice(start,end) | 切片,截取字符串(包前不包后),从start到end |
String.replace('e','o') | 将字符串中的e替换成o(只能替换第一次出现的字符) |
String.indexOf() | 搜索字符串中的内容(只检测到第一次出现的字符),没搜到返回-1 |
String.split() | 分隔 |
String.substr(start[, length]) | 截取,返回一个字符串中从指定位置开始到指定字符数的字符 |
四. 原型
Number、String、Boolean、Object这四类对象他们都会拥有一些共同的属性,这些属性是一样的,如果他们各自拥有各自的这些一样的属性的话,就会非常浪费内存,所以就有了公用属性,把所有的对象共有的属性全部放在heap内存的一个地方,当需要使用的时候,引用这个对象即可,这么操作就会减少不必要的内存浪费,而这个公有属性,也就是原型。
__ proto__就是这些共用属性的引用
由于Number、String、Boolean这三种对象比较特殊,他们是本身Number、String、Boolean的同时,也是对象,所以他们的__ proto__指向的是自己本身的公有属性,这些公有属性的__ proto__指向的才是Object的公有属性
__proto__
图中箭头从左到右连成的线叫原型链,简单理解就是原型组成的链,对象的__ proto__是原型,而原型也是一个对象,也有__ proto__属性,原型的__ proto__又是原型的原型,就这样可以一直通过__ proto__往上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了(Object的原型的__ proto__为null)
- __ proto__与prototype的区别
即使不写任何代码,JS引擎也会把原型链以及各个原型对象准备好,并且,为了不让他们被当成垃圾回收,浏览器用Object.prototype指向原型对象,所以不写代码就会有prototype
__ proto__ 是某对象公用属性的引用,是为了用户使用其共用属性中的方法而存在的 。
prototype 是浏览器写的,本身就存在,是某对象的共同属性的引用,为了不让对象的公用属性因没有被调用而被垃圾回收而存在。
五. 一些等式
var 对象 = new 函数; 是JS中声明一个对象的常用方法,可以推导出一些等式:
- 对象.__ proto__ === 函数.prototype(__ proto__是对象的属性,prototype是函数的属性)
从上面最基本的等式我们可以推导出下面的等式
- 函数.prototype.__ proto__ === Object.prototype (由于函数.prototype是一个对象)
- 函数.__ proto__ === Function.prototype(函数本身是函数,但它也是一个对象,它的构造函数是Function)
- Function.__ proto__ === Function.prototype(Function既是对象,也是函数,但它优先是个函数)
可以看出,Function.prototype 与Funciton.__ proto __ 互相引用
而且,Object.__ proto __ === Function.prototype,因为 Function 是 Object 的构造函数