简单介绍一下js中的构造函数、原型对象prototype、对象原型__proto__、原型链

构造函数
javascript 复制代码
	function Star (uname, age){
		this.uname = uname
		this.age = age
		
		this.sing = function(){ log('唱歌~') }
	}
	
	let xzq = new Star('薛之谦', 30)
	
	let ldh = new Star('刘德华', 20)
	log(ldh) // { uname: '刘德华', age: 20, sing: f }
	ldh.sing() // 唱歌~
	
	log(ldh.sing === xzq.sing) // false
复制代码
# 实例成员:构造函数内部,通过this添加的成员,如上面的:uname、age、sing
			实例成员,只能通过实例化的对象来访问,如:ldh.sing()才行,Star.sing()就不行

# 静态成员:在构造函数本身上,添加的成员,如:Star.sex = '男'
			静态成员只能通过构造函数访问,如:log(Star.sex) // 男
			不能通过实例化对象来访问(ldh.sex就不行)

# 构造函数 new 的执行过程
	1、new构造函数,可以在内存中创建一个空的对象
	2、this就会指向刚才创建的空对象
	3、执行构造函数里面的代码,就给这个空对象添加属性、方法
	4、返回这个对象(所以构造函数里面不用return)

prototype 原型对象
复制代码
# js规定,每一个构造函数都有一个prototype属性,这个prototype就是一个对象
  所以,我们可以把'公共的方法'添加到这个'原型对象prototype上'(原型对象prototype的作用就是共享方法)

  所以:公共的属性,定义到,构造函数里面
		公共的方法,定义到,原型对象prototype上
javascript 复制代码
	function Star (uname, age){
		this.uname = uname
		this.age = age
	}
	Star.prototype.sing = function(){ log('唱个歌') }
	
	let ldh = new Star('刘德华', 20)
	let xzq = new Star('薛之谦', 30)
	log(ldh.sing === xzq.sing) // true
	
	# console.log( ldh ) // 系统会自动,在对象的身上,添加一个'__proto__',指向构造函数的原型对象
	
	# prototype
		console.log( ldh.__proto__ === Star.prototype ) // true
方法的查找规则:
复制代码
	首先看`ldh对象`,它身上是否有sing()方法,如果有,就执行它的这个方法
	如果没有这个方法,但因为`__proto__`存在,就去`构造函数的原型对象prototype上`去找这个sing()方法
proto:对象原型
复制代码
	每个对象身上都有一个`__proto__`对象原型,指向`指向构造函数的原型对象prototype`
	之所以,对象可以使用`构造函数的原型对象prototype`上的属性、方法
	是因为,对象有`__proto__(对象原型)`的存在
	
	`__proto__对象原型` 和 `构造函数的原型对象prototype`是等价的
	
	`__proto__对象原型`的意义:在于为对象的查找机制提供一个方向,或者说一条线路,
	但它是一个非标准属性,因此实际开发中,不可用使用这个属性,它只是内部指向原型对象prototype

原型链
javascript 复制代码
	function Star(uname, age){
		this.uname = uname
		this.age = age
	}
	let ldh = new Start('刘德华', 123)
	
	log( ldh.__proto__ === Star.prototype ) // true
	
	log( Star.prototype.__proto__ === Object.prototype ) // true
	
	log( Star.prototype.__proto__ ) // null
原型链的查找规则
复制代码
	当访问一个对象的属性(方法)时,首先看这个对象本身有没有该属性,
	
	如果没有,就查找它的原型(也就是`__proto__对象原型`,指向的是,`prototype原型对象`)
	
	如果还没有,就查找,原型对象的原型(Object的原型对象)
	
	依次类推,直到找到Object为止(null)
	
	`_proto_对象原型`的意义:在于为对象的查找机制提供一个方向,或者说一条路线,
	但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype

可以通过原型对象,为JavaScript的(原来的)内置对象,进行扩展自定义的方法

如下:通过数组的原型对象,添加求和的方法

javascript 复制代码
	Array.prototype.sum = function(){
		console.log(this) // 指向它的调用者
		let sum = 0
		for(let i=0; i<this.length; i++){
			sum += this[i]
		}
		return sum
	}
	
	let arr = [1, 2, 3] // let arr = new Array(1,2,3)
	
	console.log(arr.sum()) // 6

constructor 指回 原来的原型对象
javascript 复制代码
// 定义一个构造函数Star
  function Star(uname, age) {
    this.uname = uname
    this.age = age
  }

  Star.prototype.sing = function () {
    console.log('唱歌~~')
  }

  // 对象.xxx:这样是向对象添加xxx属性,并不会覆盖这个对象
  Star.prototype.song = function () {
    console.log("我会唱歌")
  }

  Star.prototype.dance = function () {
    console.log("我会跳舞")
  }


  // 对象 = {}:这样是重新给对象赋值,会把原来的对象覆盖掉
  // 其实这里就是把 构造函数Star 的原型对象prototype 覆盖了,但是并不会影响uname、age在构造函数中定义的属性
  Star.prototype = {
    aaa() { console.log("我会唱歌aa") },
    bbb() { console.log("我会唱歌bbb") },
    // ....
    // ....
    // ....
  }

  // 手动用 constructor 指回原来的原型对象
  Star.prototype = {
    constructor: Star, // 指回原来的原型对象
    ccc() { console.log("我会唱歌ccc") },
    ddd() { console.log("我会唱歌ddd") },
    // ....
    // ....
    // ....
  }

  let ldh = new Star('刘德华', 123)
  console.log('ldh=', ldh) // ldh= Star {uname: '刘德华', age: 123}
  console.log('ldh.uname=', ldh.uname) // ldh.uname= 刘德华
  console.log('ldh.age=', ldh.age) // ldh.age= 123

  // ldh.sing() // Uncaught TypeError: ldh.sing is not a function
  ldh.song() // Uncaught TypeError: ldh.song is not a function

  // ldh.aaa() // Uncaught TypeError: ldh.aaa is not a function
  // ldh.bbb() //  Uncaught TypeError: ldh.bbb is not a function

  ldh.ccc() // 我会唱歌ccc.
  ldh.ddd() // 我会唱歌ddd
相关推荐
用头发抵命2 小时前
Vue 3 中优雅地集成 Video.js 播放器:从组件封装到功能定制
开发语言·javascript·ecmascript
蓝冰凌2 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛2 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉2 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
TON_G-T3 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
Irene19914 小时前
JavaScript 中 this 指向总结和箭头函数的作用域说明(附:call / apply / bind 对比总结)
javascript·this·箭头函数
2501_921930834 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-appearance(更推荐自带的Appearance)
javascript·react native·react.js
还是大剑师兰特4 小时前
Vue3 中 computed(计算属性)完整使用指南
前端·javascript·vue.js
csdn_aspnet4 小时前
查看 vite 与 vue 版本
javascript·vue.js