当前位置: 代码迷 >> 网页设计 >> 韩顺平_轻便搞定网页设计(html+css+javascript)_第32讲_构造函数_成员函数详解_学习笔记_源代码图解_PPT文档整理
  详细解决方案

韩顺平_轻便搞定网页设计(html+css+javascript)_第32讲_构造函数_成员函数详解_学习笔记_源代码图解_PPT文档整理

热度:6790   发布时间:2013-02-26 00:00:00.0
韩顺平_轻松搞定网页设计(html+css+javascript)_第32讲_构造函数_成员函数详解_学习笔记_源代码图解_PPT文档整理

文西马龙:http://blog.csdn.net/wenximalong/

js面向(基于)对象编程——类(原型对象)与对象
对象—对象(成员)函数的初步介绍

在某些情况下,我们要需要定义对象函数。比如人对象:除了有一些属性外(成员变量表示的年龄,姓名……),我们人对象还有一些行为比如:可以说话,跑步……,通过学习,我们人还可以做算术题。这是就要用函数才能完成。现在要对Person对象完善:
①添加speak函数,输出我是一个好人
②添加jisuan函数,可以计算从1+...+1000的结果
③修改jisuan函数,该方法可以接收一个数n,计算从1+...+n的结果
④添加add成员函数,可以计算两个数的和

对象——成员函数(方法)
比如:我们希望对象不但有属性,还希望他有行为。(行为在程序中要靠函数来体现)
demo1

<html>	<head>		<script language="javascript">			function Person(name,age){				//这个就是使用传入的实际参数,去初始化属性。				this.name=name;				this.age=age;				//输出自己的名字				//这里this.手腕就是一个公开的函数,函数名是show				//有一个麻烦事,先点出来。这样的方式有一个弊病,你用这样的方式分配一个函数,那么每个对象都有show这段函数代码。如p1有,p2也有等等,在一定程度上效率会有以一点影响,这个问题怎么解决,在后面讲解。这样去分配函数,会使每一个Person对象实例,都有一段这样的show函数代码,也就是show这个函数不会放在一个所谓的代码区让所有对象共享,而是每一个对象都会有一段这样的代码,这就造成一种浪费了,当然在对象不多的情况下,也无所谓,一旦对象用完了就会被垃圾回收给回收了。如果连这点浪费也要避免的话,就要用原型的方式来解决。在后面会讲解。当然,this.show类似的方法在开发中也有用到。				this.show=function(){					document.writeln("名字="+this.name); //this要带上,如果不带this,就会认为name是另外一个变量了				}				//添加jisuan函数,可以计算从1+...+1000的结果				this.jisuan=function(){					var res=0;					for(var i=1;i<=1000;i++){						res+=i;					}					return res;				}				//改进jisuan函数,可以计算从1+...+n的结果				this.jisuan2=function(n){					var res=0;					for(var i=1;i<=n;i++){						res+=i;					}					return res;				}			}			var p1=new Person("宋江",90);			p1.show();			document.writeln("<br/> res="+p1.jisuan());			document.writeln("<br/> res="+p1.jisuan2(10));		</script>	</head>	<body></body></html>
注释中一段详解


对象——成员函数
给一个对象添加(指定)函数的几种方式
方式1

function Person(){	this.name="abc";	this.age=900;}function show1(){	window.alert("hello"+this.name);}//创建一个p1对象var p1=new Person();//把show1函数,给p1.abcp1.abc=show1; //这样就相当于把show1的函数指针给它了,这个时候大家是共享的一个了,不是每个对象都有这个show1,不是每个对象都指向show1了,对比上面的demo1//把原来写在里面的show1函数,写在外面了,仅此而已//★★★带括号和不带括号的区别★★如果是p1.abc=show1();就是把show1函数的返回值交给p1.abc这个属性,即hello;如果是p1.abc=show1;就是把函数本身交给p1.abc这个属性值,this会起作用,即helloabc。p1.abc(); //调用
javascript的语法特别灵活,不在里面写,而是在外面写了函数,然后再分配给他,就好像动态分配一个对象属性一样,动态分配一个函数,这是允许的。灵活是把双刃剑。
demo2

<html>	<head>		<script language="javascript">			function Person(){				this.name="abc";				this.age=900;			}			function show1(){				window.alert("hello"+this.name);			}			var p1=new Person();			p1.abc=show1; //把show1本身给了p1.abc属性,相当于在Person类中定义的			p1.abc(); //输出helloabc			window.alert(p1.abc);//没有括号,不是p1.abc()这样的,输出function show1这个整个函数,打印函数本身			window.alert(show1);//同理和上面一样,同样没有括号,把整个function show1整个函数打印出来			window.alert(p1.abc());//输出helloabc,再输出undefined,这里是调用了,abc后面跟括号了。★★★为什么还会输出undefined★★★			window.alert(show1());//先输出hello,再输出undefined,show1的返回值。			p1.bcd=show1(); //把show1函数的返回值给P1.bcd属性,为什么没有this.name呢了,此时show1函数仅仅传递结果,对于show1函数来讲,它不知道this是指向谁			p1.bcd(); //输出hello		</script>	</head>	<body></body></html>
方式2
function Person(){	this.name="abc";	this.age=900;}var p1=new Person();p1.abc=function show1(){	window.alert("hello"+this.name);}p1.abc();

demo3

<html>	<head>		<script language="javascript">			function Person(){				this.name="abc";				this.age=900;			}			var p1=new Person();			//这个相当于把show1函数本身交给p1.abc属性了			//如同这样定义			//function Person(){			//	this.name="abc";			//	this.age=900;			//	this.abc=function(){			//		window.alert("hello"+this.name);				//	}			//}			p1.abc=function show1(){				window.alert("hello"+this.name);			}			p1.abc();//输出helloabc		</script>	</head>	<body></body></html>

方式1和方式2的区别:
在方式2中,直接把函数给p1.abc了。在方式1中,show1好多属性都可以用,如p2.abc=show1;而在方式2中,相当于function show1被p1.abc给独占了,如果p2.abc也要用,你还得把show1函数从新再写,不如在方式1中可以直接p2.abc=show1;
究竟用那种方法呢:
如同demo1中,写在类定义中的最通用。

给对象添加方法还有两种方式
第一种:
function 类名(){
this.属性;
}
var 对象名=new 类名();
function 函数名(){
//执行
}
对象名.属性名=函数名; //这样就相当于把 函数赋给 对象名.属性名,此时这个属性就表示一个函数了
对象名.属性名(); //调用

第二种:
对象名.属性名=function 函数名(){
//代码
}

对象名.属性名(); //调用


再看下面的两个案例:又会输出什么呢

function Person(){	this.name="abc1";	this.age=900;}function show1(){	window.alert("hello"+this.name); //这个this是谁在调用它,一定要看清楚了}var p1=new Person();p1.abc=show1;show1();//输出hello,在这里,this是window在调用,那么this就是window,但window的name没有值
demo4

<html>	<head>		<script language="javascript">			function Person(){				this.name="abc1"				this.age=900;			}			function show1(){				window.alert("hello"+this.name);			}			var p1=new Person();			p1.abc=show1;			show1(); //输出hello,这样直接调用的话,虽然没有找到this.name她也不再输出了,js引擎一看this.name什么都没有就不输出了。想看输出undefined,请看下面的语句,更好理解。document.writeln在调试打印很重要			document.writeln(show1());//先输出hello,然后又输出undefined,此时的this指的是window,而window的name属性没有		</script>	</head>	<body></body></html>


function Person(){	this.name="abc1";	this.age=900;}var name="北京";function show1(){	winodw.alert("hello"+this.name);}var p1=new Person();p1.abc=show1;show1();//输出hello北京,window的name属性的值定义了,var name="北京";
demo5

<html>	<head>		<script language="javascript">			function Person(){				this.name="abc2";				this.age=900;			}			var name="北京";			function show1(){				window.alert("hello"+this.name);			}			var p1=new Person();			p1.abc=show1;			p1.abc(); //输出helloabc2			show1(); //输出hello北京		</script>	</head>	<body></body></html>
★★★★★从上面可以更加深刻的认识,this,谁调用的this。

给所有对象添加(指定)函数


function Person(){	this.name="abc";	this.age=900;	this.abc=function(v1,v2){		window.alert(this.name+" "+this.age+" "+v1+" "+v2);	}}var p1=new Person();p1.abc(); //输出 abc 900 undefined undefined;虽然没有传入参数,但是函数是可以调用起来的,只是遇到 v1和v2会undefinedp1.abc("北京","天津"); //输出 abc 900 北京 天津var p2=new Person();p2.abc(); //输出 abc 900 undefined undefinedp2.abc("南京","东京"); //输出 abc 900 南京 东京//p1 p2 每个对象创建的对象属性和函数是不一样的


看看下面的代码,会输出什么呢
function Person(){	this.name="abc";	this.age=900;	this.abc=function(v1,v2){		window.alert(this.name+" "+this.age+" "+v1+" "+v2);	}}var p1=new Person();p1.name="中国";p1.abc("北京","天津");var p2=new Person();p2.abc("南京","东京");//这里主要是看p1.name会不会把this.name冲掉
demo6

<html>	<head>		<script language="javascript">			function Person(){				this.name="abc";				this.age=900;				this.abc=function(v1,v2){					window.alert(this.name+" "+this.age+" "+v1+v2);				}			}			var p1=new Person();			p1.name="中国"; //这里会把p1中的name属性冲掉。类中的this.name是一个公开的属性,p1.name确实是访问这个属性了,原先确实是abc,但是给你赋了一个新值过后,abc就会被冲掉了,变成了中国。p1.name的的确确是动态添加了,js引擎会首先检测下,p1里面是否已经有了name这个属性值,如果有的话,就在p1这个对象中,把原来的值冲掉,用新值代替,这样更容易理解。			p1.abc("北京","中国"); //输出 中国 900 北京中国			var p2=new Person();			p2.abc("南京","东京"); //输出 abc 900 南京东京		</script>	</head>	<body></body></html>

★★★★★再加深
再看使用另外一种方法来给类添加方法!
使用原型的方法来添加,这是第四种了。(前面已经讲解了三种了(1).在类定义的内部(2).外部添加如上面的:p1.abc=show1;(3).外部添加如上面的:p1.abc=function show1(){})

function Dog(){}var dog1=new Dog();dog1.shout=function(){	window.alert("小狗");}dog1.shout();var dog2=new Dog();dog2.shout(); //这里会报错
========>>>

function Dog(){}var dog1=new Dog();Dog.prototype.shout=function(){	window.alert("小狗");} // 这里就是让所有的Dog对象共享同一个shout属性function(){}dog1.shout();var dog2=new Dog();dog2.shout();//这里ok

此时就讲到了在demo1中的麻烦事,如在类中定义,this.show=function(){};这种定义方法,在有些时候,老板或项目经理会对你不满意,因为你每创建一个p1,p2,p3...每一个都会有这个show属性,就相当于每个对象实例都有this.show=function(){};这段代码。

内存分析图

图片大,在新窗口中打开图片,观看完整图片。



如果我们对象很多,就不是件好事,因为每一个对象实例都带有这段代码。
prototype是原型,prototype上绑定的所有都是共享的,独一份的。
demo7

<html>	<head>		<script language="javascript">			function Dog(){			}			//希望所有的对象,共享某个函数			//使用prototype[绑定在类上的] 去绑定一个函数给shout			Dog.prototype.shout=function(){				window.alert("小狗");			}			var dog1=new Dog();			dog1.shout();			var dog2=new Dog();			dog2.shout();			window.alert(dog1.shout==dog2.shout); //true			//扩展			var dog3=new Dog();			var dog4=new Dog();			window.alert("dog3==dog4"+(dog3==dog4));//false,dog3和dog4指向的堆区地址不一样			var dog5=dog4; // 让dog5指向dog4			window.alert("dog4==dog5"+(dog4==dog5));//true,dog4和dog5指向的堆区地址一样		</script>	</head>	<body></body></html>

内存图分析

图片大,在新窗口中打开图片,观看完整图片。


结论:前面的三种方法有一个问题:那就是每个对象,独占函数代码,这样如果对象很多,则会影响效率,js设计者,给我们提供了另一个方法 原型法 prototype

补讲:==号的作用
①当 ==的两边都是字符串的时候,则比较内容 相等否。
②如 ==的两边是数字,则数的大小是否相等
③如 ==的两边是对象 或者是对象函数,则比较地址是否相通。


 韩顺平_php从入门到精通_视频教程_学习笔记_源代码图解_PPT文档整理_目录




  相关解决方案