谈谈原型与原型链

1.jpg

记得刚学前端那会,一个面试的问我,知不知道原型与原型链,然后就懵了,回来才发现就是python的继承那块知识。

数据结构

说到这个先说下数据类型。

基本数据类型(值类型) (作为一般数据存在内存中)

  • String
  • Number
  • boolean
  • undefined
  • null (初始赋值 ,表示要赋值为对象,结束赋值,让变量变为一个垃圾对象回收,切断内存联系)

对象类型(引用类型) (作为地址数据存在内存中)

  • Object
  • Function
  • Array

原型

  1. 函数的prototype属性(显式原型属性) 每个函数都有一个prototype属性,默认指向一个空对象(即叫做:原型对象) 原型对象中有一个constructor,它指向函数对象
  2. 给原型对象添加属性(一般是方法) 作用:函数的所有实例对象自动拥有原型中的属性(方法)
  3. 每个实例对象都有一个__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的原型对象

20200509 231539.jpg

还是网上的图比较直观

yuanxlian.jpg
此图关键点: 关键点一:所有函数都是Function的实例对象,Function这个构造函数也由Function自己产生Function=new Function(),所以Function的隐式原型属性等于其显示原型属性

          
  • 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

总结:

  1. 构造函数Foo,Object,Function都是由Function这个函数产生的,所以他们的隐式属性__proto__都先等于Function.prototype,Function.prototype是Function自己的实例对象,Function.prototype.__proto__最终指向一个空Object的实例对象(参考关键点二)
  2. 对象隐式原型的值等于构造函数显示原型的值
  3. 构造函数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()
(完)
Python生成一个最简单的rss.xml
feedgen库
简单尝试下Xray
直接使用一键安装脚本了
西安四日游
历史古城 大国巅峰
vite创建vue3项目 eslint+prettier+stylelint
eslint+prettier+stylelint配置
vue3.2 Keepalive踩坑
vite-plugin-vue-setup-extend 插件给script标签赋值name属性,小问题花费我一天找答案
武汉二日游
感谢武汉 感谢李文亮医生
等待你的评论