原型及原型链模式
-
每一个函数数据类型的值,都有一个天生自带的属性:prototype(原型),这个属性的属性值是一个对象(“用来存储实例公用属性和方法”)
- 普通的函数
- 类(自定义类和内置类)
-
在prototype这个对象中,有一个天生自带的属性:constructor,这个属性存储的是当前函数本身
Fn.prototype.constructor === Fn
-
每一个对象数据类型的值,也有一个天生自带的属性:_proto_,这个属性指向“所属类的原型prototype”
- 普通对象、数组、正则、Math、日期、类数组等等
- 实例也是对象数据类型的值
- 函数的原型prototype属性的值也是对象类型的
- 函数也是对象数据类型的值
原型链查找机制
1.先找自己私有的属性,有则调取使用,没有继续找 2.基于__proto__找所属类原型上的方法(Fn.prototype),如果还没有则继续基于__proto__往上找...一直找到Object.prototype为止
hasOwnProperty
检测某一个属性名是否为当前对象的私有属性
“in” :检测这个属性是否属于某个对象(不管是私有属性还是公有属性,只要是它的属性,结果就为TRUE)
let ary = [10,20,30];
console.log('0' in ary); //=>TRUE
console.log('push' in ary); //=>TRUE
console.log(ary.hasOwnProperty('0')); //=>TRUE
console.log(ary.hasOwnProperty('push')); //=>FALSE "push"是它公有的属性不是私有的
console.log(Array.prototype.hasOwnProperty('push')); //=>TRUE 是公有还是私有属性,需要看相对谁来说的
console.log(Array.prototype.hasOwnProperty('hasOwnProperty')); //=>FALSE
console.log(Object.prototype.hasOwnProperty('hasOwnProperty')); //=>TRUE
//自己堆中有的就是私有属性,需要基于__proto__查找的就是公有属性(__proto__在IE浏览器中(EDGE除外)给保护起来了,不让我们在代码中操作它)
检测某个属性是否为对象的公有属性:hasPubProperty
方法:是它的属性,但是不是私有的
//基于内置类原型扩展方法
Object.prototype.hasPubProperty = function (property) {
//=>验证传递的属性名合法性(一般只能是数字或字符串等基本值)
let x = ["string", "number", "boolean"],
y = typeof property;
if (!x.includes(y)) return false;
//=>开始校验是否为公有的属性(方法中的THIS就是要校验的对象)
let n = property in this,
m = this.hasOwnProperty(property);
return n && !m;
}
console.log(Array.prototype.hasPubProperty('push')); //=>FALSE
console.log([].hasPubProperty('push')); //=>TRUE