zoukankan      html  css  js  c++  java
  • js面向对象学习

    原文地址:js面向对象学习笔记

    一、对象概念

    对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”。也就是一组名值对的无序集合。

    对象的特性(不可直接访问),也就是属性包含两种,数据属性和访问器属性。

    1、数据属性又包含

    • Configurable  //表示能否通过delete删除,默认为true;
    • Enumerable  //表示能否通过for-in循环返回属性,默认为true;
    • Writable     //表示能否修改属性的值,默认为true;
    • Value              //包含属性的数据值,默认为undefined

    要修改默认属性的特性,必须使用ECMAscript5的object.defineProperty(属性的对象, 属性的名字, 需要修改的属性特性)方法。例如:

    	// 1、修改默认的属性特性,
    	var person = {};
    	Object.defineProperty(person, "name", {
    		writable : false,
    		value : "abc"
    	});
    
    	alert(person.name);  //abc
    	person.name = "bcd";
    	alert(person.name);  //abc而不是bcd,这里在非严格模式下会忽略,在严格模式下会报错
    

    一旦做了这样的设置之后,就不可再次修改了,否则就会报错。

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

    还有一点要注意的是,在调用Object.defineProperty()方法时,如果不指定第三个参数中的(Configurable,writable,Enumerable),也就是要修改的属性,那么他们都会默认为false

    	// 1、修改默认的属性特性,
    	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
    

      

    2、访问器属性

    • Configurable
    • enumerable
    • get                //在读取属性时调用的函数
    • set                //在写入属性时调用的函数
    	// 2、定义访问器属性
    	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(对象, 需要添加的属性);

    	// 3、定义多个属性
    	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对象是很有作用的,基础嘛,基础永远是必须的,继续学习~

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

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

    (我发现等号分割线没上面短杠分割线好看)

    二、创建对象

    前几天看到这样的面试题,js创建对象的方法有几种,只知道是3种写法,并不清楚原理是什么,今天整理了下。

    1. 工厂模式
    2. 构造函数模式
    3. 原型模式
    4. 组合使用构造函数模式和原型模式

    1、工厂模式

    	// 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();
    

    2、构造函数模式

    构造函数的函数名大写开头,其他函数都是小写

    	// 5、构造函数模式
    	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语句

    构造函数的问题:

    当对象有多个实例时,这些实例的所有方法都是不同的,因为它都会创建一遍。

    	// 5、构造函数模式
    	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
    

     

    3、原型模式

    优点:可以让所有对象实例共享它所包含的属性和方法。

    	// 6、原型模式
    	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是一个指针,指向一个对象,而这个对象就是包含所有实例共享的属性和方法,也就是说,通过调用构造函数而创建的那个对象实例的原型对象。

    原型模式的问题:

    	// 6、原型模式
    	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
    

    4、组合使用原型模式和构造函数模式

    通过以上的例子我们可以知道,构造函数模式,创建的方法都是不同的,都是实例自己拥有的,而原型模式定义的属性和方法是共享的,那么结合起来使用真是perfect。

    	// 6、混合模式
    	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种。

  • 相关阅读:
    MVC系列-7.更新
    MVC系列-6.注册页面
    MVC系列-5.详细信息
    MVC系列-4.布局页
    MVC系列-3.数据显示
    MVC系列-2.数据处理-登陆
    MVC系列-1.MVC入门
    bootstrap table 服务器端分页--ashx+ajax
    swift学习第八天:元组
    swift学习第七天:字典
  • 原文地址:https://www.cnblogs.com/jhmydear/p/4630737.html
Copyright © 2011-2022 走看看