js高程-6 面向对象的程序设计 总结

介绍:面向对象都有类的概念,但是ECMAscript没有,因此它的对象与基于类的对象有所不同。ECMAscript中每一个对象都是基于引用类型(可以是原生也可以是开发人员定义的类型)创建。

6.1 理解对象

创建方式:1.直接为对象添加属性

 var person = new Object();
	person.name = 'xiaoming';
	person.age = 18;
	person.job = 'software Engineer';
	person.sayName = function() {
		console.log(this.name);
	};

2.对象字面量语法

var person = {
			name: 'xiaoming',
			age: 18,
			job: 'software Engineer',
			sayName: function() {
				console.log(this.name);
			}
		};

ECMAscript有两种属性类型:数据属性和访问器属性

6.2创建对象

由于以上的方法会产生大量重复的代码,为了解决这个问题使用工厂模式来创建对象。

6.2.1工厂模式

由于ECMAscript无法创建类,开发人员发明了一种函数来封装以特定的接口创建对象。如下:

function creatPerson(name, age, job) {
			var o = new Object();
			o.name = name;
			o.age = age;
			o.job = job;
			o.sayName = function() {
				alert(this.name);
			};
			return o;
		}
		var person1 = creatPerson('xiaoming', 18, 'software Engineer');
		var person2 = creatPerson('greg', 20, 'doctor');
6.2.2构造函数模式

除了原生的构造函数(Array,Object),还有自定义类型的构造函数,可以自定义对象类型的属性和方法,如下:

function Person(name, age, job) {
			this.name = name;
			this.age = age;
			this.job = job;
			this.sayName = function() {
				alert(this.name);
			};
		}
		var person1 = new Person('xiaoming', 18, 'software Engineer');
		var person2 = new Person('greg', 20, 'doctor');

要点:构造函数开头应该是大写字母,person1和person2保存着Person不同的实例,这两个对象都有一个constructor(构造函数)属性,该属性指向Person。
可以通过instanceof来检测对象类型:

console.log(person1 instanceof Object);//true
console.log(person1 instanceof Person);//true
console.log(person2 instanceof Object);//true
console.log(person2 instanceof Person);//true

对象的类型既是Object也是Person类型,这意味着可以把自定义创建函数的实例标志为一种特定的类型,这也是构造函数胜于工厂函数的地方。

1.将构造函数当做函数
2.构造函数的问题

person1和person2都有一个sayName()的方法,但这两个方法不是属于同一个function实例,为了解决两个函数同做一件事,可以使用原型模式来解决。

6.2.3原型模式

我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象包含着所有实例共享的属性和方法,也就是说prototype就是通过构造函数创建的对象实例的原型对象。但与构造函数不同的是:

function Person() {
			Person.prototype.name = 'xiaoming';
			Person.prototype.age = 18;
			Person.prototype.job = 'software Engineer';
			Person.prototype.sayName = function() {
				alert(this.name);
			};
		}
		var person1 = new Person();
		person1.sayName();
		var person2 = new Person();
		person2.sayName();

新对象的属性和方法是共享的,person1和person2访问的是同一个属性和同一个sayName()方法。

1.理解原型对象

只要创建一个新的函数就会为该函数创建一个prototype属性,这个属性指向函数的原型对象。所有原型对象都会自动获得constructor(构造函数)属性,这个函数包含一个指向prototype属性所在函数的指针。如前面的例子:Person.prototype.constructor指向Person。
以下是各个对象间的关系图:
在这里插入图片描述
当为对象实例添加属性时,这个属性会屏蔽原型对象中保存的同名属性。使用delete即可删除实例中的属性,从而重新访问原型对象中的属性。

function Person() {
			Person.prototype.name = 'xiaoming';
			Person.prototype.age = 18;
			Person.prototype.job = 'software Engineer';
			Person.prototype.sayName = function() {
				alert(this.name);
			};
		}
		var person1 = new Person();
		var person2 = new Person();
		person1.name = 'jack';//给实例添加属性
		alert(person1.name);//jack---来自实例
		alert(person2.name);//xiaoming---来自原型对象
        delete person1.name;
		alert(person1.name); //xiaoming---来自原型对象
		alert(person2.name); //xiaoming---来自原型对象

使用hasOwnPrototype()方法可以检测一个属性是否在实例还是在原型中,只有在属性属于实例才会返回true。

function Person() {
			Person.prototype.name = 'xiaoming';
			Person.prototype.age = 18;
			Person.prototype.job = 'software Engineer';
			Person.prototype.sayName = function() {
				alert(this.name);
			};
		}
		var person1 = new Person();
		var person2 = new Person();
		alert(person1.hasOwnProperty('name'));//false
2.原型与in操作符

有两种方式使用in操作符,一种是在for-in循环中,一种是单独使用。单独使用时,会在对象包含属性时返回true。无论属性是在实例还是在原型中。

function Person() {
			Person.prototype.name = 'xiaoming';
			Person.prototype.age = 18;
			Person.prototype.job = 'software Engineer';
			Person.prototype.sayName = function() {
				alert(this.name);
			};
		}
		var person1 = new Person();
		var person2 = new Person();
		alert('name' in person1);//true

同时使用hasOwnProperty()和in可以判断属性属于实例还是属于原型,如下:

function hasPrototypeProperty(Object, name) {
			return !Object.hasOwnProperty(name) && name in Object;
		}

只要in操作符返回true并且hasOwnProperty()返回false,就可以确定属性是属于原型。

发布了26 篇原创文章 · 获赞 6 · 访问量 5080

猜你喜欢

转载自blog.csdn.net/Blablabla_/article/details/103930058