构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立开的-》实例识别
function CreateJsPerson(name,age){ this.name = name; this.age = age; } CreateJsPerson.prototype.writeJs = function () { console.log("my name is" + this.name) } var p1 =new CreateJsPerson("张三",20); var p2 =new CreateJsPerson("李四",30); console.log(p1.writeJs === p2.writeJs) // true
1.基于构造函数模式的原型模式解决了 方法或者属性公有的问题-》把实例之间相同的属性和方法提取成公有的属性和方法(想让谁公有就把它放在prototype上即可)
1)每一个函数数据类型(普通函数,类)都有一个天生自带的属性:prototype(原型),并且这个属性是一个对象数据类型的值
2)并且在prototype上浏览器天生给它加了一个属性constructor(构造函数),属性值是当前函数(类)本身
3)每一个对象数据类型(普通对象,实例,prototype...)也天生自带一个属性:__proto__,属性值是当前实例所属类的原型(prototype),所有的对象数据类型,都是Object的一个实例,Object是一个对象类,也是一个类(是一个函数数据类型),天生自带prototype
Array是一个数组类,也是函数数据类型的类
对于内置类来说不用new Array也可以创建一个实例,用对象字面量的形式创建
function Fn() { this.x = 100;
this.sun = function () {} } Fn.prototype.getX = function () { console.log(this.x); }
Fn.prototype.sum = function () {}
var f1 = new Fn; var f2 = new Fn; console.log(Fn.prototype.constructor === Fn); // true
2.Object是JS中所有对象数据类型的基类(最顶层的类)
1)f1 instanceof Object -> true 因为f1通过__proto__可以向上级查找,不管有多少级,最后总能找到Object
2)在Object.prototype上没有__proto__这个属性
3.原型链模式
f1.hasOwnProperty("x"); // hasOwnProperty是f1的一个属性
但是我们发现在f1的私有属性上并没有这个方法,那如何处理的呢?
1)通过 对象名.属性名 的方式获取属性值的时候,首先在对象私有属性上进行查找,如果私有中存在这个属性,则获取的是私有的属性值;
2)如果私有的没有则通过__proto__找到所属类的原型(类的原型上定义的属性和方法都是当前实例的公有的属性和方法),原型上存在的话,获取的是公有的属性值,如果原型上也没有,则继续通过原型上的__proto__继续向上查找,一直找到Object.prototype为止...
-> 这种查找的机制,就是我们的“原型链模式”
测试题:
1)f1.getX === f2.getX -> true
2)f1.__proto__.getX === f2.getX // f1.__proto__.getX忽略查找私有的,直接查找公有的,而f2.getX先查询私有的,在查询公有的
3)f1.getX===Fn.prototype.getX; // true
4)f1.sum === f2.__proto__.sum // false f1.sum是私有的,而f2.__proto__.sum是公有的原型链上的
5)f1.sum === Fn.prototype.sum // false f1.sum是私有的,而Fn.prototype.sum是公有的原型链上的
f1.hasOwnProperty -》f1.__proto__.__proto__.hasOwnProperty
在IE浏览器中, 我们的原型模式也是同样的原理,但是IE浏览器怕你通过__proto__把公有的修改,禁止我们使用__proto__
f1.sum = function(){} 原来没有的话就是增加一个sum,原来有的话就是修改,把私有的修改了
f1.__proto__.sum = function () {} 修改所属类原型上的sum
Fn.prototype.sum = function () {} 修改所属类原型上的sum