原型和原型链

270 阅读3分钟

JS变量中有一种变量叫全局变量,是浏览器自带的,通常叫做window变量。

该变量的属性有两种:

一种是ECMAScript规定的比如parseInt(),parseFloat(),Number(),String(),Object(),Boolean(),document等内置对象;

另一种是浏览器私有的,每个浏览器都不一样的,比如alert(),prompt(),confirm(),console()这样的非内置对象。

上面的内置对象Number(),String(),Object(),Boolean(),除了我们常见的可以进行不同数据类型之间转换的作用之外,还有另一种作用,就是利用new可以声明一个对象。

比如:

var n=new Number(1)

Number()函数会把1变成一个对象,此时1是一个对象,里面有不同的属性对应不同的值,只能用valueOf()函数获取它原来的值1或者用toString()函数来获取对象的字符串形式。

var n=1;
n.toString();

执行上述代码的时候,内存中会声明一个临时变量temp,对应的栈内存存入堆内存地址,调用temp的toString方法来得到结果字符串1,然后把这个结果返回给n.toString作为它的值,这句执行完就把temp毁灭掉,所以简单数据类型也能有自己的属性,因为js自己把简单数据类型转换成复杂数据类型,便于调用复杂数据类型的一些属性。

那么上面window的公有属性的共同点是什么呢,就是它们声明的对象里都有一样的属性,例如toString,valueOf函数。

为了避免占用内存,所以在堆内存里选择一个地方作为公用属性的位置,在需要使用到这些属性的时候根据存的地址找到属性调用,而不是每个对象都有自己单独的toString等属性。把这些公用属性作为一个隐藏的键值对,键名_ _proto_ _,对应的键值为地址,指向公用属性存放的位置。

每一个方法的公有属性是不一样的,对于Number来说,公有属性有toFixed,toExp等,也有toString,但是和Object的toString是不一样的,所以在number的公有属性内存里除了这些公有属性,会另外存一个_ _proto _ _指向一个地址,地址中存着所有对象object的公有属性在浏览器中如果一个属性没有被引用就会被当做垃圾回收掉,那这些公有属性被谁引用的呢,是被Object的prototype引用的,即对象的原型,所以:

obj.__proto__===Object(代表不同数据类型,也可以是number或string等等).prototype;

prototype是浏览器给的,是对对象的公用属性的引用,__proto__是对象自身对公用属性的引用所以可以得出以下结论:

给出一个对象,如果想要调用它的某一个属性,先去它自带的公有属性__proto__里找,如果没有就去对应的数据类型的prototype里找,如果还没有,就去所有数据类型的公有属性Object.prototype里找。Object.prototype是树状结构的最高一层,所以Object.__proto__=null。这样的过程,就叫做原型链

通过以上结论可以得出以下关系:

对象.__proto__===函数.prototype

函数.prototype.__proto__===Object.prototype

函数.__proto__===Function.prototype

Function.__proto__===Function.prototype

Function.prototype.__proto__===Object.prototype



常用的字符串操作函数:

trim(),去掉字符串前后的空格返回字符串;

contact(),连接两个字符串,得到新字符串;

slice(a,b),分割字符串,从第a个到b-1个;

replace(a,b),用b替换a;