function Fn() {
this.x = 100;
this.y = 200;
this.getX = function () {
console.log(this.x)
}
}
Fn.prototype.getX = function () {
console.log(this.x)
}
Fn.prototype.getY = function () {
console.log(this.y)
}
let f1 = new Fn
let f2 = new Fn
console.log(f1.getX === f2.getX)
console.log(f1.getY === f2.getY)
console.log(f1.__proto__.getY === Fn.__proto__.getY)
console.log(f1.__proto__.getX === f2.getX)
console.log(f1.getX === Fn.__proto__.getX)
console.log(f1.constructor)
console.log(Fn.prototype.__proto__.constructor)
f1.getX()
f1.__proto__.getX()
f2.getY()
Fn.prototype.getY()
/**
* EC(G)
* vo
* 0x000 Fn函数堆内存
* ”代码字符串“
* prototype =》
* 0x001 Fn.prototype (当前类的)原型对象
* constructor:Fn(自身)
* =》
* getX: function...
* getY: function...
* __proto__
*
* 详解:
* 原型上的getX和getY
* 相对于f1/f2两个实例来讲是其公共的属性和方法
*
*
* 属性是私有还是公有-》是相对的
*
*
*
*
*
* 0x002 let f1 = new Fn
* 实例对象
* x = 100
* y = 200
* getX:function...
*
*
* 0x003 let f2 = new Fn
* 实例对象
* x = 100
* y = 200
* getX:function...
*/
function Fn() {
this.x = 100;
this.y = 200;
this.getX = function () {
console.log(this.x)
}
}
Fn.prototype.getX = function () {
console.log(this.x)
}
Fn.prototype.getY = function () {
console.log(this.y)
}
let f1 = new Fn
let f2 = new Fn
console.log(f1.getX === f2.getX) // => false
console.log(f1.getY === f2.getY) // => true
console.log(f1.__proto__.getY === Fn.prototype.getY) // true
console.log(f1.__proto__.getX === f2.getX) // false
console.log(f1.getX === Fn.__proto__.getX) // false
console.log(f1.constructor) // Fn
console.log(Fn.prototype.__proto__.constructor) // Object
f1.getX() // 100
f1.__proto__.getX() // undefined
f2.getY() // 200
Fn.prototype.getY() // undefined
/**
* JS中面向对象的底层处理机制
* =》存储当前类所属实例调用的公用属性和方法
* 1.每一个(除箭头函数外的)函数数据类型,都天生自带一个属性:prototype原型属性,属性值是一个对象(Function.prototype除外),并且原型对象中自带一个属性:constructor,属性值是当前构造函数
* 1.普通函数、箭头函数、生成器函数
* 2.构造函数「一般指自定义类」
* 3.内置类「内置构造函数」
* 2&3 prototype 针对类游泳,对于普通函数来讲没啥用
* ...
* =》 为了找到所属类原型上的公用方法
* 2.每一个对象数据类型值,都天生自带一个属性:__proto__原型链属性(隐式原型)属性值指向所属类的原型对象prototype
* 普通对象,数组对象,正则对象、日期对象...
* prototype原型对象
* 实例对象
* 函数也是对象
* ...
* * 所有对象都是Object内置类的实例
*/
/**
* Object 内置类 「函数类型」
* ”【native code】“
* ------------------
* prototype => 0x000
*
*
* 0x000 Object.prototype 原型对象
* constructor:Object
* ------------------
* hasOwnPrpperty
* isPrototypeof
* toStringOf
* ...
* ----------------------------------------------------------------
* __proto__: null ***注意:为啥是null,原因:Object.prototype原型对象也是Object对象类的一个实例,__proto__如果要指向,就指向自己了,这样没有意义:所以作为基类原型上的__proto__是null即可!!
*
*
*
* 成员访问「不论是遍历还是直接访问等」
* f1.x -> 首先找自己私有的属性,私有中存在操作的就是私有的,私有的不存在,则默认基于__proto__找所属类prototype上的。如果还没有,则基于prototype上的__proto__继续向上查找...直到找到Object.prototype位置「我们把这个套查找机制,称之为原型链」
*
* 「公有属性」
* 每个实例都可以基于__proto__找到
*
* f1.__proto__.getX -> 跳过私有属性的查找,直接找所属类原型上的公有属性和方法「__proto__在Ie中不兼容,浏览器把他起来了,不让用」
* f1.getX() -> 实例先找到对应的方法「基于原型链」,再把方法执行,如果遇到this,则分析this是谁「函数执行看点前面是谁」
* 找到的是私有getX,this -> f1
* console.log(this.x) -> console.log(f1.x) => 100
* f1.__proto__.getX()
* 公共的getX,this -> f1.__proto__
* console.log(this.x) => console.log(f1.__proto__.x) => undefined
* f2.getY()
* 公共的getY, this->f2
* console.log(this,y) => console.log(f2,y) => 200
*
* Fn.prototype.getY()
* 原型上的getY, this -> Fn.prototype
* console.log(this,y) => console.log(Fn.prototype,y) =>undefined
*
*/
/**
* f1 instanceof 检测某个实例是否属于这个类
*
* 我也不知道new谁出来的
* Fn.prototype 一定 不是Fn的实例
* 一般只有new Fn出来的才是他的实例
*
*
*/