谈谈原型与原型链
记得刚学前端那会,一个面试的问我,知不知道原型与原型链,然后就懵了,回来才发现就是python
的继承那块知识。
数据结构
说到这个先说下数据类型。
基本数据类型(值类型) (作为一般数据存在内存中)
- String
- Number
- boolean
- undefined
- null (初始赋值 ,表示要赋值为对象,结束赋值,让变量变为一个垃圾对象回收,切断内存联系)
对象类型(引用类型) (作为地址数据存在内存中)
- Object
- Function
- Array
原型
- 函数的prototype属性(显式原型属性) 每个函数都有一个prototype属性,默认指向一个空对象(即叫做:原型对象) 原型对象中有一个constructor,它指向函数对象
- 给原型对象添加属性(一般是方法) 作用:函数的所有实例对象自动拥有原型中的属性(方法)
- 每个实例对象都有一个__proto__,称为隐式原型(属性),对象隐式原型的值等于构造函数显示原型的值
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
//构造一个函数Fn
function Fn(){
//构造时 this.proptype={}
}
console.log(Fn.prototype) // Fn有一个prototype属性指向一个原型对象
console.log(Fn.prototype.constructor ===Fn) //原型对象中有一个constructor,它指向函数对象
Fn.prototype.test=()=>"我是Fn的test方法" //给原型对象添加属性(一般是方法)
//创建一个Fn的实例对象
var fn=new Fn() //new做了什么事情? this.__proto__=Fn.prototype
console.log(fn.__proto__===Fn.prototype) //true 对象隐式原型的值等于构造函数显示原型的值
console.log(fn.test()) // "我是Fn的test方法" 函数的所有实例对象自动拥有原型中的属性(方法)
上述代码的图解 显然对象找属性会从自身找起,之后顺着隐式原型属性__proto__绿色链条开始一直找,一直找到Object的原型对象
还是网上的图比较直观
- 1
console.log(Function.__proto__===Function.prototype) //true
关键点二:函数的显示原型指向的对象默认是空Object的实例对象(Object除外)
- 1
- 2
- 3
console.log(Fn.prototype instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(Function.prototype instanceof Object) //true
关键点三: Object的原型对象是原型链尽头
- 1
console.log(Object.prototype.__proto__) //null
总结:
- 构造函数Foo,Object,Function都是由Function这个函数产生的,所以他们的隐式属性__proto__都先等于Function.prototype,Function.prototype是Function自己的实例对象,Function.prototype.__proto__最终指向一个空Object的实例对象(参考关键点二)
- 对象隐式原型的值等于构造函数显示原型的值
- 构造函数Foo,Object,Function都会产生自己得显示属性,他们的显示属性最终会指向Object
运用,探秘instanceof
数据类型判断 typeof 和 instanceof
typeof: 可以判断:undefined/数值/字符串/布尔值/function 不能判断:null,Object,array
instance of 表达式 A instanceof B (理解:A是否是B的实例,所以B的实例就是B.prototype) 如果B函数的显示原型(prototype)对象在A对象的原型链上 返回true,否则返回false
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
var b1={
b2:[1,2,3],
b3:function(){
console.log("b2函数")
}
}
var a = new Number(1)
function Fn(){
//构造时 this.proptype={}
}
var fn=new Fn()
console.log(typeof a )//object
console.log(typeof 1 ) //number
console.log(typeof [1,2,3]) //object
console.log(typeof null) //object
console.log(typeof b1) //object
console.log(typeof b1.b2) //object
console.log(typeof b1.b3) //function
console.log(typeof undefined) //undefined
console.log( 1 instanceof Object ) //false instanceof判断一个对象是否是另一个对象的实例,而数字1是基本数据类型,不是对象,
console.log( [1,2,3] instanceof Array ) //true
console.log( [1,2,3] instanceof Object ) //true
console.log( fn instanceof Function ) //Fn是构造函数生成的对象 所以Fn是一个函数对象,就像[1,2,3] 是 Array对象一样, [1,2,3] 也是 Object
console.log( fn instanceof Object ) //所以函数也是对象 函数一种特殊的对象
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
console.log( typeof Function) //function
console.log( typeof String ) //function
console.log( typeof Number) //function
console.log( typeof Object ) //function
console.log( typeof Array) //function都是构造函数
//数据类型判断
console.log( Object instanceof Function) //true Object是一个构造函数 是New Function产生的 所以Object实例对象的__proto__指向构造函数Function的prototype
console.log( Function instanceof Object) //true
console.log( Object instanceof Object) //true Object是一个构造函数 是New Function产生的 所以Object实例对象的__proto__指向构造函数Function的prototype Function的prototype实例对象的__proto__指向一个空的Object对象
console.log( Array instanceof Object) //true 构造函数也是对象
小练习
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
function A(){
}
A.prototype.n=1
var b =new A()
A.prototype={
n:2,
m:3
}
var c=new A()
console.log(b.n,b.m,c.n,c.m) //1,undefined,2,3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
function F(){}
Object.prototype.a=function(){
console.log('a()')
}
Function.prototype.b=function(){
console.log("b()")
}
var f= new F()
f.a()
f.b()
F.a()
F.b()
(完)
0条看法
最新最后最热
等待你的评论