javascript中的静态属性,实例属性,原型属性/(静态方法,实例方法,原型方法)以及各种继承方式

了解javascript中对于 静态属性,实例属性,原型属性的理解。

静态属性:定义在构造函数上的属性,只能由构造函数来进行调用
实例属性:定义在构造函数内部的属性,使用绑定在this上面。只能实例去访
问,构造函数访问不到
原型属性:定义在构造函数原型上的方法。实例可以访问到。构造函数可以
通过prototype属性来访问
eg:

function Family(txt){
//实例属性
 this.abc=txt;
}
//静态属性
Family.staticAbc="staticAbc";
//原型属性
Family.prototype.protoAbc="protoAbc";

那么三者区别以及优缺点呢
在这里插入图片描述

可以看出 对于实例而言
可以访问实例属性 以及原型属性。而不能访问静态属性。需要通过constructor来间接访问
对于构造函数来说
只可以访问静态属性。不能访问静态属性与原型属性如果要访问原型属性 需要借助于 prototype

好了说完了这三者之间的关系 咋么再来聊聊 在js中普遍用到的继承方式

第一种,原型链继承

function Father(){
	this.txt="Father";
	this.other={
		sonNum:2,
		job:"CEO"
	}
}
Father.prototype.eyeColor="black"
Father.prototype.skinColor="yello";
function Son(){
	this.txt="Son"
}

Son.prototype=new Father();
Son.prototype.eyeColor="blue"
const insSon=new Son()


内部原型指向如图:
在这里插入图片描述
控制台运行结果如图:
在这里插入图片描述

//此时我们访问 insSon的eyeColor
insSon.eyeColor
// blue
//但是 此时我们 重新给eyeColor属性赋值
insSon.eyeColor="orange"
//此时我们再此访问eyeColor属性
insSon.eyeColor
//orange

此时insSon如图所示:
在这里插入图片描述
我们重新给eyeColor属性赋值。直接放在了Son的实例属性上面。而没有放在Father的原型属性上。
所以 js引擎去查找eyeColor的时候 直接找到的是Son上的值。并没有通过原型链查找。

对于 父组件中的 引用类型属性。如果是修改引用类型属性中的某个值,那么 insSon与insSon2中 对应的引用类型属性都会跟着变化。
eg:
在这里插入图片描述
如果 重新赋值引用引用属性 就和 eyeColor相同。
在这里插入图片描述

借用构造函数

伪造构造函数 是对原型链继承方式的一种优化 是为了解决 原型链继承的一些缺点。
1.可以传参到父类
2.修改父类引用类型属性,不会发生多个实例跟着变化。
eg:

function Father(...arr){
	this.txt="Father";
	this.other={
		sonNum:2,
		job:"CEO"
	};
	this.params=arr;
}
Father.prototype.eyeColor="black"
Father.prototype.skinColor="yello";

function Son(fatherParams,...sonParams){
    Father.call(this,...fatherParams);
	this.txt="Son";
	this.sonParams=sonParams[0];
}
Son.prototype.eyeColor="yellow";

let fatherParams=["父参1","父参2"];
let sonParams=["子参1","子参2"];
const insSon=new Son(fatherParams,sonParams);

在这里插入图片描述
在son的构造函数中 使用 call函数 。使得最后实例化后的son实例对象中 新增了params与other属性
至于 call的作用以及原理 可以参考其他文章或者后续我自己整理对他相关的介绍。
但是这种方式也有其不足
eg:
在这里插入图片描述
我们在Father的原型对象上面定义了skinColor属性
但是我们使用Son访问时找不到此属性。
也就是 借用构造函数 这种继承方式 继承不了父类prototype上面的函数与属性。
这个根本原因 是因为 使用了call方法。只使用了Father的实例方法和属性。并不能使用Father的原型属性。子类没有链接指向父类的原型链,所以访问不到。

组合继承

function Father(...arr){
	this.txt="Father";
	this.other={
		sonNum:2,
		job:"CEO"
	};
	this.params=arr;
}
Father.prototype.eyeColor="black"
Father.prototype.skinColor="yello";

function Son(fatherParams,...sonParams){
    Father.call(this,...fatherParams);
	this.txt="Son";
	this.sonParams=sonParams[0];
}
Son.prototype=new Father();
Son.prototype.eyeColor="yellow";

let fatherParams=["父参1","父参2"];
let sonParams=["子参1","子参2"];
const insSon=new Son(fatherParams,sonParams);

在这里插入图片描述
这种方式是在 借用构造函数的基础上,来弥补借用构造函数的不足之处。
但是缺点就是 实例化了2次父类。

原型式继承

原型式继承采用Object.create函数实现
先来了解下 Object.create

在这里插入图片描述
翻译:
在这里插入图片描述
eg:
此处引用官网的例子:

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // Inherited properties can be overwritten

me.printIntroduction();
// Expected output: "My name is Matthew. Am I human? true"

在这里插入图片描述
翻译成大白话就是 Object.create创建一个实例 并且这个实例的原型指向第一个形参。
自己可以模拟一下Object.create的实现
参考文章 Prototypal Inheritance in JavaScript

function object(o) {
	function F(){}
	F.prototype = o
	return new F()
}

这样写是不是很形象

这种思想 我觉得是对原型链继承的一种升级。来摆脱一层一层new的限制。思路是相同的。

const father={
	this.txt="Father";
	this.other={
		sonNum:2,
		job:"CEO"
	};
}
const son=Object.create(father)

在这里插入图片描述
优点: 代码整洁易理解。
缺点:父类引用类型属性容易被共用

寄生式继承

寄生式继承是对 原型式继承的一种强化

function createFamily(original){
  // 继承一个对象 返回新函数
  var clone = Object.create(original);
  // do something 以某种方式来增强对象
  clone.some = function(){}; // 方法
  clone.obkoro1 = '封装继承过程'; // 属性
  return clone; // 返回这个对象
}

本质上与原型式继承无异,只是用函数包起来一层。用于对函数的一种增强

寄生组合式继承

function Father(){
	this.txt="Father";
	this.other={
		sonNum:2,
		job:"CEO"
	}
}
Father.prototype.eyeColor="black"
Father.prototype.skinColor="yello";
function Son(){
	this.txt="Son"
}

function createFamily(son,father){
	//创建father.prototype的一个新对象
	const fatherPrototype=Object.create(father.prototype);
	//将son的原型指向 新创建的这个对象。
	son.prototype=fatherPrototype;
	//修正 fatherPrototype的构造函数指向问题
	son.prototype.constructor=son;
}
createFamily(son,father)
Son.prototype=new Father();
Son.prototype.eyeColor="blue"
const insSon=new Son()

这种方式应该是最优解。我听其他博主说。至于为啥,还需要进一步 自己去理解。后续会持续更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值