javascript 对象和函数

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>objectandfunction.html</title>
	
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
	<script type="text/javascript" src="../js/jquery-1.11.3.js"></script>
  
  <body>
  	<div id="div"></div>
	<script type="text/javascript">
	// <![CDATA[
		//如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:
		var global = (function () {
			return this;
		})();
		function show(str) {
			$("#div").append($("<p></p>").text("" + str));
		}
	
		//JSON 文本转换为 JavaScript 对象
		//JSON 最常见的用法之一,是从 web 服务器上读取 JSON 数据(作为文件或作为 HttpRequest),将 JSON 数据转换为 JavaScript 对象,然后在网页中使用该数据。
		//JSON 解析器
		//由于 JSON 语法是 JavaScript 语法的子集,JavaScript 函数 eval() 可用于将 JSON 文本转换为 JavaScript 对象。
		//eval() 函数使用的是 JavaScript 编译器,可解析 JSON 文本,然后生成 JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误:
		//var obj = eval ("(" + txt + ")");
		//eval() 函数可编译并执行任何 JavaScript 代码。这隐藏了一个潜在的安全问题。
		//使用 JSON 解析器将 JSON 转换为 JavaScript 对象是更安全的做法。JSON 解析器只能识别 JSON 文本,而不会编译脚本。
		var jsontxt = '{"employees":[' +
			'{"firstName":"Bill","lastName":"Gates" },' +
			'{"firstName":"George","lastName":"Bush" },' +
			'{"firstName":"Thomas","lastName":"Carter" }]}';
		var jsonobj = JSON.parse(jsontxt);
		show([jsonobj.employees[0].firstName, jsonobj.employees[0].lastName]);	//Bill,Gates
		
		//javascript 变量和函数名称是大小写敏感的
		function CaseSensitive() {}
		try {
			caseSensitive();
		} catch (error) {
			show(error);	//ReferenceError: caseSensitive is not defined
		}
		
		//函数上下文中的变量对象VO
		//形式参数和arguments对象指向相同的变量
		//未传递进来的形参和arguments[]为undefined,修改时不会互相影响
		//模拟函数重载:用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载
		function foo(x, y, z) {
			// 声明的函数参数数量arguments (x, y, z)
		  	show("声明的函数参数数量:" + foo.length); 			// 3
		  	// 真正传进来的参数个数(only x, y)
		  	show("真正传进来的参数个数:" + arguments.length);	// 2
		  	// 参数的callee是函数自身
		  	show(arguments.callee === foo); // true
		  	// 参数共享
		  	show(x === arguments[0]); 		// true
		  	show(x);						// 10
		 	//参数同步
		  	arguments[0] = 20;
		  	show(x); 						// 20
		 	x = 30;
		  	show(arguments[0]); 			// 30
		  	// 不过,没有传进来的参数z,和参数的第3个索引值是不共享的
		  	z = 40;
		  	show(arguments[2]); 			// undefined
		  	arguments[2] = 50;
		  	show(z); 						// 40
		}
		foo(10, 20);
		
		//函数声明(缩写为FD)是这样一种函数:
		//1.有一个特定的名称
		//2.在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体(FunctionBody)中
		//3.在进入上下文阶段创建
		//4.影响变量对象VO
		//这种函数类型的主要特点在于它们仅仅影响变量对象(即存储在上下文的VO中的变量对象)。
		function funcDefine() {
			//  ...
		}
		
		//函数表达式(缩写为FE)是这样一种函数:
		//1.在源码中须出现在表达式的位置
		//2.有可选的名称
		//3.不会影响变量对象
		//4.在代码执行阶段创建
		//这种函数类型的主要特点在于它在源码中总是处在表达式的位置。
		var funcEx = function () {};
		//自执行函数表达式
		(function () {
			show("hello world");
		})();
		
		//当函数表达式FE有一个名称(称为命名函数表达式,缩写为NFE)时,将会出现一个重要的特点。
		//从定义中我们知道函数表达式不会影响一个上下文的变量对象VO
		//(那样意味着既不可能通过名称在函数声明之前调用它,也不可能在声明之后调用它)。
		//但是,FE在递归调用中可以通过名称调用自身。
		var nfe = function testNFE() {};
		try {
			testNFE();		//未定义
		} catch(error) {
			show(error);	//ReferenceError: testNFE is not defined
		}
		
		var varNFE = function funNFE() {
			show([arguments.callee === varNFE,
		    	arguments.callee === funNFE]);
		};
		varNFE(); 	// [true, true]
		
		//通过函数构造器Function创建的函数
		//既然这种函数对象也有自己的特色,我们将它与FD和FE区分开来。
		//其主要特点在于这种函数的[[Scope]]属性仅包含全局对象:
		var z = 10;
		function newFunc() {
			var z = 20;
			var y = 30;
			var bar = new Function('show(z); show(y);');
			try{
		  		bar(); 	
			}catch(error){ show(error); }	
		}
		newFunc();	// 10, "y" 未定义
		
		//变量对象VO:
		//任何时候,变量只能通过使用var关键字才能声明。
		//隐式声明仅仅是给全局对象创建了一个新属性(但它不是变量)。
		//关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{DontDelete},
		//这个特性的含义就是不能用delete操作符直接删除变量属性。
		show(x);			//function x() {}
		var x = 10;
		show(x);			//10
		function x() {}
		x = 20;
		show(x);			//20
		//var 定义的变量不能删除
		delete x;
		show(x);			//20
		//global.y简单属性可以删除
		y = 100;
		delete y;
		try {
			show(y);
		} catch (error) {
			show(error);	//ReferenceError: y is not defined
		}
		
		var foo = {x: 10};
		var bar = {
			x: 20,
			test: function () {
		    	show(this === bar); 
		    	show(this.x); 
		  	}
		};
		bar.test();		// true, 20
		 
		foo.test = bar.test;
		// 这里this指向foo
		// 尽管调用的是相同的function
		foo.test(); 	// false, 10


		//基本类型可以像对象类型一样使用,包括访问其属性、对其属性赋值(尽管实际上不起作用,但是形式上可以)。
		//之所以能这样去使用基本类型,是因为JavaScript引擎内部在处理对某个基本类型 a进行形如a.sth的操作时,
		//会在内部临时创建一个对应的包装类型(对数字类型来说就是Number类型)的临时对象,并把对基本类型的操作代理到对这个临时对象身上,
		//使得对基本类型的属性访问看起来像对象一样。但是在操作完成后,临时对象就扔掉了,下次再访问时,会重新建立临时对象,当然对之前的临时对象的修改都不会有效了。
		var aa = 10;
		aa.prop = 20;
		show(aa.prop + aa);	//NaN
		
		var bb = 'hello ';
		bb.prop = 'world';
		show(bb + bb.prop);	//helloundefined

		var cc = new Number(10);
		cc.prop = 20;
		show(cc.prop + cc);	//30
		
		var dd = function() {};
		dd.prop = 'hello ';
		show(dd.prop + dd);	//hello function () {}
	// ]]>
	</script>
  </head>
  </body>
</html>

相关推荐