JavaScript 之 面向对象

何为对象

对象是包含着键值对的无序散列表

关于属性

  1. 数据属性
    	const obj = {}
    	Object.defineProperty(obj, 'name', {
    		configurable: true,
    		enumerable: true,
    		write: true,
    		value: 'Daniel'
    	})
    
  2. 访问器属性
    	const obj = {}
    	Object.defineProperty(obj, 'age', {
    		configurable: true,
    		enumerable: true,
    		get: function () {
    			return this._age
    		},
    		set: function (value) {
    			this._age = value < 18 ? value : 18
    		}
    	})
    
    	obj.age = 16
    	console.info('obj.age: ', obj.age) // 16
    
    	obj.age = 25
    	console.info('obj.age: ', obj.age) // 18
    
  3. 批量设置属性
    	const obj = {}
    	Object.defineProperties(obj, {
    		name: {
    			value: 'Daniel',
    		},
    		age: {
    			get: function() {
    				return 25
    			}
    		},
    	})
    
  4. 获取属性描述符
    	Object.getOwbPropertyDescriptor(obj, key)
    

创建对象

1. 工厂模式

	function createPerson(name, age) {
		const o = Object()
		
		o.name = name
		o.age = age
		
		return o
	}
	const person = createPerson('Daniel', 25) // { name: 'Daniel', age: 25 }

2. 构造函数模式

new 操作符

	function Person(name, age) {
		this.name = name
		this.age = age
	}
	const person = new Person('Daniel', 25) // { name: 'Daniel', age: 25 }

3. 原型模式

	function Person() {}
	Person.prototype = {
		constructor: Person,
		name: 'Daniel',
		sayName: () => console.info(this.name)
	}

	const person = new Person()

番外篇:啥是原型对象

Function.prototype 对象:

  • prototype 对象拥有所有实例共享的属性和方法
  • prototype 对象的 constructor 属性指向函数自身

缺点

  • 构造函数不可传参
  • 引用属性共享可被每个实例更新

4. 组合模式

	function Person(name, age) {
		this.name = name
		this.age = age
	}
	Person.prototype.sayHi = function () {
		console.info(`Hi, My name is ${this.name}`)
	}

	const person = new Person('Daniel', 25)
	person.sayHello() // Hi, My name is Daniel

5. 动态原型模式

一些面向对象开发人员不习惯将方法的声明放在构造器外部,所以有了下面这样的声明:

	function Person(name) {
		this.name = name
		if (typeof this.sayHi !== 'function') {
			Person.prototype.sayHi = function () {
				console.info(`Hi, My name is ${this.name}`)
			}
		}
	}

6. 寄生构造函数模式

可用于扩展已有对象

	function Enhanced(array) {
		const enhancedArray = Array.isArray(array) ? array : []

		enhancedArray.combineValue = function () {
			return enhancedArray.reduce((total, curr) => total + curr)
		}

		return enhancedArray
	}

	const hanced = new Enhancd([1, 2, 3])
	hanced.combineValue() // 6

Tip:这种情况下创建的实例与构造函数间没有任何关系哦,因为返回的其它类型的实例

7. 稳妥构造函数模式

比较极端的场景
特点:

  • 无公共属性
  • 方法中不引用 this 对象
	function Person(name) {
		const o = new Object()
		
		o.sayHi = function() {
			console.info(`Hi, My name is ${name}`)
		}

		return o
	}

	const person = new Person('Daniel')
	person.sayHi() // Hi, My name is Daniel

继承

核心点:通过 原型链 共享属性和方法 实现继承

首先理一下 函数(构造函数)、原型对象 和 实例 之前的关系:

拥有
constructor 属性
__proto__ 内部属性
new 实例化
构造函数
原型对象
实例对象

1. 通过原型链继承

	function SubType() {}
	SubType.protptype = new SuperType()

缺点

  • 实例会共享原型链上的引用属性

2. 借用构造函数

	function SubType(name) {
		SuperType.call(this)
		this.name = name
	}

优点

  • 继承父类的实例属性
  • 构造函数可传参

缺点

  • 木有继承父类原型上的共享属性与方法,伐开心

3. 组合继承

	function SubType(name) {
		SuperType.call(this)
		this.name = name
	}
	SubType.prototype = new SuperType()

优点

  • 父类实例属性和原型属性、方法 全都要

缺点

  • 继承过程中调用了两次 父类 构造函数,父类表示不开心
  • 解决方案在 寄生组合式继承 里

4. 原型式继承

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

原型式继承同样会有引用类型属性共享的问题,ES5 通过 Object.create() 方法规范了原型式继承

5. 寄生式继承

寄生式继承是在原型式继承上的扩展,可用于增强对象:

	function createAnother(original) {
		const clone = object(original)
		
		clone.sayHi = function () {
			console.info('Hi')
		}
		
		return clone
	}

6. 寄生组合式继承

其背后思路是:用寄生式继承来继承父类的原型,再将结果指定给子类型的原型

	function inheritPrototype(SubType, SuperType) {
		const prototype = object(SuperType.prototype)
		prototype.constructor = SubType
		SubType.prototype = prototype
	}

	function SubType(name) {
		this.name = name
	}
	
	inheritPrototype(SubType, SuperType)
	
	SubType.prototype.sayHi = function() {
		console.info(`Hi, My name is ${this.name}`)
	}
	

完·End

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值