面向对象编程

        面向对象编程 —— Object Oriented Programming,简称 OOP ,是一种编程开发思想

创建对象的方式 

工厂模式

        创建对象交给一个工厂方法来实现,可以传递参数,但主要缺点是无法识别对象类型和来源,因为创建对象都是使用Object的原生构造函数来完成的

function createPerson(name, age, job) {
	var o = new Object();
    o.name = name;
	o.age = age;
	o.job = job;
	o.getName = function() {
		return this.name;
	}
	return o;   //使用 return 返回生成的对象实例
}
var person1 = createPerson('Jack', 19, 'SoftWare Engineer')
var person2 = createPerson('Tom', 25, 'Mechanical Engineer')

构造函数模式

        解决了获取对象类型和来源的问题,但是重复创建方法,浪费内存

function Person(name, age, job) {
	this.name = name;
	this.age = age;
	this.job = job;
	this.getName = function() {
		return this.name;
	}
}
var person1 = new Person('Jack', 19, 'SoftWare Engineer')
var person2 = new Person('Tom', 23, 'Mechanical Engineer')

①通过constructor获取对象的来源

console.log(person1.constructor)

②通过instanceof判断对象的来源

console.log(person1 instanceof Person)
console.log(person1 instanceof Object)

new方法实例对象(补充)

        要创建Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象创建

实际创建经过以下四个过程:

a) 创建一个空对象(底层实现)

b) 将函数的作用域赋给新对象(即this指向新对象)

c) 执行构造函数的代码

d) 返回该对象(底层实现)

function Person(name, age, job) {
	// 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象
	// let instance = {}
	// 然后让内部的 this 指向 instance 对象
	// this = instance
	// 接下来所有针对 this 的操作实际上操作的就是 instance
				
	this.name = name;
	this.age = age;
	this.job = job;
	this.getName = function() {
		return this.name;
	}
				
	// 在函数的结尾处会将 this 返回,也就是 instance
	// return this
}

 

原型模式

        能够节省内存,但是无法为构造函数传递初始化参数,最主要是当对象的属性是引用数据类型时,它的值(指针)是不变的,总是指向同一个外部对象,所有实例对该对象的操作都会影响其它实例

原型对象:JS每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个空对象,它是所有通过new操作符使用函数创建的实例的原型对象

①所有在原型中创建的属性和方法都直接被所有实例共享

function Person() {}
Person.prototype.name = 'Jack'  //使用原型来添加属性
Person.prototype.age = 19
Person.prototype.job = 'Mechanical Engineer'
Person.prototype.getName = function() {
	return this.name
}
var person1 = new Person()
console.log(person1)
var person2 = new Person()
console.log(person2)
			

②实例中属性会覆盖原型对象中的属性:原型模式创建的对象实例,其属性是共享原型对象的;但也可以自己实例中重新进行定义,在查找时,就不从原型对象获取,而是根据搜索原则,得到本实例的返回

function Person() {}
Person.prototype.name = 'Jack'  //使用原型来添加属性
Person.prototype.age = 19
Person.prototype.job = 'Mechanical Engineer'
Person.prototype.getName = function() {
	return this.name
}
var person1 = new Person()
person1.name = '黄小米'
console.log(person1.getName())
var person2 = new Person()
console.log(person2.getName())

③每当调用构造函数创建一个新实例后,该实例的内部包含一个指针,指向构造函数的原型属性。(一般名为_ _proto_ _,chrome浏览器现更改为[[prototype]])

④函数及函数原型之间形成循环指向:只要创建一个新函数,就会为该函数创建一个prototype属性。在默认情况下,所有prototype属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针

组合构造函数及原型模式

        目前最为常用的定义类型方式,构造函数模式用于定义实例的属性(支持向构造函数传递参数),原型模式用于定义方法和共享的属性。因此每个实例都会有自己的一份实例属性的副本,但同时又共享着对方方法的引用,最大限度的节约内存

function Person(name, age, job) {
	this.name = name
	this.age = age
	this.job = job
	this.lessons = ['Math', 'Physics']
}
Person.prototype.getName = function() {
	return this.name;
}
var person1 = new Person('Jack', 19, 'SoftWare Engneer')
person1.lessons.push('Biology')
console.log(person1.lessons)
var person2 = new Person('Tom', 39, 'Mechanical Engneer')
console.log(person2.lessons)
console.log(person1.getName === person2.getName) //共享原型中定义方法

定义原型方法的方法:

// 方法一:constructor指向存在问题
Person.prototype = {
	constructor: Person, //原型方式会将对象的constructor变为Object,此处强制指回Person
	getName: function() {
		return this.name;
	}
}
// 方法二:constructor指向没有问题,逐项赋值
Person.prototype.getName = function() {
	return this.name;
}

 

修改this指向

call:立即运行n个参数

function Point(x,y){
	this.x = x
	this.y = y
}
let person = {
	name:'黄小米'
}
Point.call(person,1,1)
console.log(person)

apply:立即运行,数组传参,两个参数

function Point(x,y){
	this.x = x
	this.y = y
}
let person = {
	name:'黄小米'
}
Point.apply(person,[1,1])
console.log(person)

bind:绑定this,生成一个新的函数

function Point(x,y){
	this.x = x
	this.y = y
}
let person = {
	name:'黄小米'
}
let creat = Point.bind(person)
creat(1,1)
console.log(person)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值