js面向對象學習 - 對象概念及建立對象

原文地址:js面向對象學習筆記javascript

1、對象概念java

對象是什麼?對象是「無序屬性的集合,其屬性能夠包括基本值,對象或者函數」。也就是一組名值對的無序集合。面試

對象的特性(不可直接訪問),也就是屬性包含兩種,數據屬性和訪問器屬性。函數

一、數據屬性又包含學習

  • Configurable  //表示可否經過delete刪除,默認爲true;
  • Enumerable  //表示可否經過for-in循環返回屬性,默認爲true;
  • Writable     //表示可否修改屬性的值,默認爲true;
  • Value              //包含屬性的數據值,默認爲undefined

要修改默認屬性的特性,必須使用ECMAscript5的object.defineProperty(屬性的對象, 屬性的名字, 須要修改的屬性特性)方法。例如:this

	// 一、修改默認的屬性特性,
	var person = {};
	Object.defineProperty(person, "name", {
		writable : false,
		value : "abc"
	});

	alert(person.name);  //abc
	person.name = "bcd";
	alert(person.name);  //abc而不是bcd,這裏在非嚴格模式下會忽略,在嚴格模式下會報錯

一旦作了這樣的設置以後,就不可再次修改了,不然就會報錯。spa

	// 一、修改默認的屬性特性,
	var person = {};
	Object.defineProperty(person, "name", {
		writable : false,
		value : "abc"
	});
	Object.defineProperty(person, "name", {
		writable : true,
	});

還有一點要注意的是,在調用Object.defineProperty()方法時,若是不指定第三個參數中的(Configurable,writable,Enumerable),也就是要修改的屬性,那麼他們都會默認爲false.net

	// 一、修改默認的屬性特性,
	var person = {};
	person.sex = "nan";
	Object.defineProperty(person, "name", {  //在這裏咱們修改name的值,不指定第三個參數中的屬性,看結果
		// writable : false,
		value : "abc"
	});

	alert(person.name);  //abc
	person.name = "bcd";
	alert(person.name);  //abc,不可修改,默認爲false
	person.sex = "nv";   //沒有調用defineProperty,默認仍是爲true
	alert(person.sex);   //nv

  

二、訪問器屬性prototype

  • Configurable
  • enumerable
  • get                //在讀取屬性時調用的函數
  • set                //在寫入屬性時調用的函數
	// 二、定義訪問器屬性
	var book = {
		_year : 2014,
		edition : 1
	}
	Object.defineProperty(book, 'year', {     //year在這裏就是定義訪問器屬性
		get : function(){
			return this._year;
		},
		set : function(value){
			this._year = value;
			this.edition += value-2004;
		}
	});
	book.year = 2005;
	alert(book.edition);  // 2

 

當須要定義多個屬性時,可使用defineProperties(對象, 須要添加的屬性);指針

	// 三、定義多個屬性
	var books = {};

	Object.defineProperties(books, {
		_year : {
			value : 2004
		},
		edition : {
			value : 1
		},
		year : {
			get : function(){
				return this._year;
			},
			set : function(value){
				this._year = value;
				this.edition += value-2004;
			}
		}
	});
	// books.year = 2006;
	// alert(books._year);   ////這裏就不能用這個方法賦值了,這裏返回2004
	var descriptor = Object.getOwnPropertyDescriptor(books, "_year");
	descriptor.value = 2006;
	alert(descriptor.value);  //2006
	// alert(typeof descriptor.get);

 

這些概念彷佛用的地方比較少,可是去理解js對象是頗有做用的,基礎嘛,基礎永遠是必須的,繼續學習~

 

/*---------------------------------------------------------------------------------------------------------------------------------------*/

/*==========================================================================*/

(我發現等號分割線沒上面短槓分割線好看)

 

2、建立對象

前幾天看到這樣的面試題,js建立對象的方法有幾種,只知道是3種寫法,並不清楚原理是什麼,今天整理了下。

  1. 工廠模式
  2. 構造函數模式
  3. 原型模式
  4. 組合使用構造函數模式和原型模式

 

一、工廠模式

	// 四、工廠模式
	function createPerson(name){
		var obj = new Object();
		obj.name = name;

		obj.show = function(){
			alert(this.name);
		}
		return obj;
	}
	var person  = createPerson("ym");//不須要使用new
	person.show();

 

二、構造函數模式

構造函數的函數名大寫開頭,其餘函數都是小寫

	// 五、構造函數模式
	function Person(name, sex){
		this.name = name;
		var sex = sex; //私有
		this.show = function(){
			alert(sex);
		}
	}
	var person1 = new Person('ym', 'nan');
	alert(person1.name);    //ym
	alert(person1.sex);     //undefined
	person1.show();         //nan

與工廠模式的區別:

  • 沒有顯示建立對象
  • 直接賦值給this對象
  • 沒有return語句

構造函數的問題:

當對象有多個實例時,這些實例的全部方法都是不一樣的,由於它都會建立一遍。

	// 五、構造函數模式
	function Person(name, sex){
		this.name = name;
		var sex = sex; //私有
		this.show = function(){
			alert(sex);
		}
	}
	var person1 = new Person('ym', 'nan');
	var person2 = new Person('jh', 'nv');
	// alert(person1 instanceof Person);   //true
	alert(person1.show == person2.show);   //false

 

三、原型模式

優勢:可讓全部對象實例共享它所包含的屬性和方法。

	// 六、原型模式
	function Person2(){}

	Person2.prototype = {
		name : "ym",
		sex : 'nan',
		show : function(){
			alert(this.name);
		}
	}

	var a = new Person2();
	var b = new Person2();
	alert(a.show == b.show);  //true

關於prototype,對它的理解也是很是重要的,過幾天再學習整理,看了好屢次了,以爲仍是理解不夠。

prototype是一個指針,指向一個對象,而這個對象就是包含全部實例共享的屬性和方法,也就是說,經過調用構造函數而建立的那個對象實例的原型對象。

 

原型模式的問題:

	// 六、原型模式
	function Person2(){}

	Person2.prototype = {
		name : "ym",
		sex : 'nan',
		love : ['a', 'b'],
		show : function(){
			alert(this.name);
		}
	}

	var a = new Person2();
	a.love.push('c');
	var b = new Person2();
	a.love.push('d');
	// alert(a.show == b.show);
	alert(a.love);   //abcd
	alert(b.love);  //abcd

 

四、組合使用原型模式和構造函數模式

經過以上的例子咱們能夠知道,構造函數模式,建立的方法都是不一樣的,都是實例本身擁有的,而原型模式定義的屬性和方法是共享的,那麼結合起來使用真是perfect。

	// 六、混合模式
	function Perfect(name, sex){
		this.name = name;
		this.sex = sex;
		this.love = ['a' , 'b'];
	}

	Perfect.prototype = {
		constructor : Perfect,
		show : function(){
			alert(this.love);
		}
	}
	var a = new Perfect('a', 'nan');
	var b = new Perfect('b', 'nv');
	a.love.push('c');
	b.love.push('d');
	a.show();   //abc
	b.show();	//abd

總算是整理完了,我也理解了原來建立對象的3種方法就是上面說的前3點,但最好用的是第4種。

相關文章
相關標籤/搜索