首页 > 编程语言 > 详细

JavaScript的面向对象

时间:2021-05-30 00:33:45      阅读:16      评论:0      收藏:0      [点我收藏+]

创建对象

ES5没有正式支持面向对象,而是利用原型式进行继承。ES6引入类,是对ES5的类和原型继承进行封装的语法糖。

工厂模式

是指一个接收固定参数的函数,用new Object()的形式,用参数创建对象及其属性和方法。

function create(name,age,job){
	let o = new Object();
	o.name = name;
	o.age = age;
	o.job = job;
	o.sayName = function(){
		console.log(this.name);
	};
	return o;
}

let person1 = create("alex",20,"SE");

能够创建多个类似的对象,但是没办法确定对象的类型,它只是Object类型。

构造函数模式

原生构造函数:Object Array,通过自定义构造函数,为自己的对象类型定义属性和方法。

方法特点:

  • 没有显示创建对象
  • 属性和方法赋值给了this
  • 没有return
function Person(name,age,job){
	this.name = name;
	this.age = age;
	this.job = job;
	this.sayName = function(){
		console.log(this.name);
	};
	return o;
}
let person1 = new Person("alex",20,"SE"); //传统调用方法,新建Person对象
let o = new Object();
Person.call(o,"alex",20,"SE"); //在另一个对象的作用域中调用,以o作为构造函数的this值,属性和方法添加到对象o中

对象特点:

  • 实例能够被标识成特定类型了(相对于工厂模式的一大进步)
  • 对象的类型判断为Person和Object都可以(自定义对象继承自Object)
console.log(person1 instanceof Person) //true
console.log(person1 instanceof Object) //true
  • 对象的constructor属性指向构造函数
console.log(person1.constructor == Person) //true

构造函数的缺点

构造函数定义的方法会在每个实例上都创建一遍。所以每个实例的同一个函数都不是一个实例。

原型模式

解决构造函数模式创建函数实例的缺点,利用函数的prototype(原型),共享属性和方法。

方法特点

  • 将构造函数中的值或方法直接赋值给原型
function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 20;
Person.prototype.job = "SE";
Person.prototype.sayName = function(){console.log(this.name);};

let person1 = new Person(); //新建Person对象
person1.sayName(); //"Nicholas"

对象特点

  • 每次通过构造函数创建实例的时候,实例内都有_proto_属性可以访问该实例的原型(只限Firfox、Safari、Chrome)
  • 构造函数通过prototype属性指向原型,原型通过constructor属性指向构造函数
  • 有几个方法建立实例和原型的关系
    • isPrototypeOf()
    • getPrototypeOf()

属性调用

1 属性查找及覆盖
  • 按照属性或方法的名字进行查找,先查找实例本身
  • 若实例本身没有,则查找其原型
  • 若原型没有,则查找原型的原型,以此类推

因此如果想覆盖原型的属性,那么就在实例中添加一个同名的属性。

2 属性删除

若在实例中或者原型中添加了同名的属性,但是想删除了,那么需要用到delete操作符

delete person1.name;
3 查看属性是否为自己实例的属性

可以用hasOwnProperty()方法看属性是否是实例本身的,是则返回true

person1.hasOwnProperty("name"); //true or false
4 in 操作符

in操作符会在可以通过该对象访问指定属性的时候,返回true,无论是通过对象实例还是对象原型。

console.log("name" in person1) //ture

所以,如果hasOwnProperty返回false in操作符返回true,属性就是在原型上。

继承

原型链

当实例1的原型是原型2的实例,那么就会构成一个 实例1-->原型1(实例2)-->原型2的一个原型链。
介绍原型链有助于理解继承过程,后面会直接介绍继承的方法

如图所示:

技术分享图片

确定原型实例关系的方法

  • instanceof
  • isPrototypeOf()
    如果原型出现在这个实例的原型链中,那么就会返回true

方法覆盖和新增

继承了父类之后,经常要新增方法或者覆盖父类的方法,那就要等原型赋值之后,在对原型新增方法或者覆盖方法。

function SuperType(){
	this.property=true;
};
SuperType.prototype.getSuperValue = function(){
	return this.property;
}
function SubType(){
	this.subProperty = false;
}
SubType.prototype = new SuperType();
//新方法
SubType.prototype.getSubValue = function(){
	return this.subproperty;
}
//修改旧方法
SubType.prototype.getSuperValue = function(){
	return false;
}

注:以对象字面量方式创建原型的方法的时候,相当于重写原型,破坏原来的原型链。

SubType.prototype = new SuperType();
//这样添加新方法,导致原型被重写,上一句无效
SubType.prototype = {
	getSubValue(){
		return this.subProperty;
	}
	get SuperValue(){
		return this.superProperty;
	}
}

原型链继承的问题

原型包含引用值时,不能够实现每个实例封装的特性。所以一般属性值会写在构造函数中,方法写在原型内。
1 但是在原型链中,父原型的实例变成了子实例的原型,属性放在构造函数里也会出现问题了。
2 子类型在实例化的时候,不能给父类型的构造函数传递参数。

所以原型链不会单独进行使用

JavaScript的面向对象

原文:https://www.cnblogs.com/zhangjw83/p/14826625.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!