原型
- 每一个函数数据类型的值,都有一个天生自带的属性:
prototype(原型)
,这个属性的属性值是一个对象(用来存储实例公用的属性和方法的
)- 普通函数
- 类(自定义类和内置类)
2.在prototype这个对象中,有一个天生自带的属性:constructor
,这个属性存储的是当前函数本身
Fn.prototype.constructor === Fn
复制代码
-
每一个对象数据类型的值,也有一个天生自带的属性:
__proto__
,这个属性指向所属类的原型prototype
- 普通对象、对象、数组、正则、Math、Date、类数组…
- 实例是对象
- 函数的原型prototype也是对象
- 函数也是对象数据类型的值
原型链查找机制
- 先找自己私有的属性,有则调取使用,没有就继续找
- 基于
__proto__
找所属类原型上的方法,如果还没有则继续基于__proto__
往上找…一直找到Object.prototype为止
原型链方法中this的问题
- 方法执行,前面若有点,点前面的就是this
- 把方法中的this替换成点前面的
- 再基于原型链查找的方法确定结果
function Fn(){
//this: f1
this.x = 100
this.y = 200
this.say = function(){
console.log(this.x)
}
}
Fn.prototype.say = function(){
console.log(this.y)
}
Fn.prototype.eat = function(){
console.log(this.x + this.y)
}
Fn.prototype.write = function(){
this.z = 1000
}
let f1 = new Fn
f1.say() //this: f1 => f1.x => 100
f1.eat() //this: f1 =>f1.x + f1.y => 300
f1.__proto__.say() //this: f1.__proto__ => f1.__proto__.x => undefined
Fn.prototype.eat() //this: Fn.prototyp => Fn.prototyp.x + Fn.prototyp.y => NaN
f1.write() //this: f1 => f1.z = 1000=>给f1设置了一个私有属性
Fn.prototype.write() //this: Fn.prototype => Fn.prototype.z = 1000 => 给f1设置了一个公有属性
复制代码
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 hasOwnProperty是Object的私有属性
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END