JS:原型
什么是引用数据?
例如object function为js中的引用数据;
引用数据就是一种内存空间,是一种数据容器;
数组是一种有下标的数据容器;
对象是一种键值对的数据容器;
函数是一个有代码块和作用域的数据容器;
数据容器就是可以存储很多数据的引用。
定义:
原型是一个对象,通过原型可以实现对象的属性继承,对象中都包含了一个[[Prototype]]内部属性,这个属性所对应的就是该对象的原型。
注意:
1、所有的对象都有一个属性叫 __proto__ 代表的是这个对象的原型对象。
2、[[Prototype]]作为对象的内部属性,是不能被直接访问的。为了方便查看一个对象的原型,提供了__proto__的访问器。
3、在JavaScript的原型对象中,还包含一个”constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数。
4、所有实例的原型引用的是函数的prototype属性,只有函数对象才会有这个属性。
例1:
function Person(name, age) { this.name = name; this.age = age; } var p1 = new Person('lili',10); console.log(p1); var p2 = new Person('jack',12); console.log(p2);
console.log(f1 == f2); //false
console.log(p1.__proto__==p2.__proto__); //true
理解:p1 p2不是同一个对象,但使用的是同一个内存空间。
例2:
function fn() { this.life = 1; } //隐式操作:fn.prototye={} function fm() { this.color = "black"; } //隐式操作:fm.prototye={} var f1 = new fn(); var f2 = new fm(); console.log(f1.__proto__ === f2.__proto__) ; //false console.log(f1.__proto__ === fn.prototype); //true console.log(f2.__proto__ === fm.prototype) ; //true console.log(f1.__proto__ === fm.prototype); //false // 所有函数都有name,lebgth,prototye属性,用函数创建对象, // 创建出来的对象的原型对象就是prototye属性引用的对象 // prototye属性中引用了一个系统内置的对象:new Object()/{} var obj1 = {}; var obj2 = {}; console.log(obj1 == obj2) ; //false
理解:
例子中使用了'====',严格判断了类型和数据是否相等。
f1 、f2不是通过同一个函数创建出的新对象,因此原型对象不可能相等;
通过原函数创建的新对象与原函数使用的是同一个原型。
例3:
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.fistname = "li"; var f1 = new Person(); f1.age = 20; var f2 = new Person(); var f3 = new Person(); console.log(f1.fistname,f2.fistname,f3.fistname); console.log(f2.age);
打印结果:
li li li
undefined
理解:
为创建的Person函数的原型对象添加一个成员属性firstname并赋值为“li”;
分别创建了f1 f2 f3三个不同的新对象,但共用Person的原型对象,但f1添加了一个成员age并赋值为20;
当在f1 f2 f3中去寻找firstname的时候,先在每个函数的第一层找,没有就到原型对象中去找,因为共用一个原型,因此找到的都是同一个firstname;
f2没有age成员,f1的age也不在原型中,因此f2的age未定义。
例4:
function fn() { this.a = 20; } function fm() { this.a = 30; } fm.prototype.fn = new fn(); var f1 = new fm(); console.log(f1); //{a:30,__proto__:{fn:{a:20}}}
打印结果:
fm {a: 30}
理解:
首先创建了fn fm两个函数,为fm的原型添加了一个成员fn(变量名),其值为新创建的对象;
再创建了一个对象f1,其原型对象与fm共用的同一个。