javascript prototype原型

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>prototype.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>

  </head>
  
  <body>
	<div id="div"></div>
	<script type="text/javascript">
		// <![CDATA[
		//$(document).ready(function() {
		//});
		
		//如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:
		var global = (function () {
			return this;
		})();
		var count = 0;
		function show(str) {
			$("#div").append($("<p></p>").text("" + str));
		}
		

		//新创建对象的原型是从当前时刻函数的prototype属性获取的,这意味着同一个构造函数创建的两个对象的原型可以不同;
		//这是因为构造函数的prototype属性也可以不同。
		//function.funcName声明的是static函数
		function BaseClass() {
			this.name = "BaseClassName";
			this.showMsg = function() {
				show("BaseClass::showMsg::" + this.name);   
			};
			this.baseShowMsg = function() {
				show("BaseClass::baseShowMsg::" + this.name);
			};
		}
		BaseClass.showMsg = function() {
		    show("BaseClass::showMsg static name = "  + this.name);
		};
		
		function ExtendClass() {
			this.name = "ExtendClassName";
		    this.showMsg = function () {
		        show("ExtendClass::showMsg::" + this.name);
		    };
		}
		ExtendClass.showMsg = function() {
		    show("ExtendClass::showMsg static name = " + this.name);
		};
		
		//通过prototype实现继承
		ExtendClass.prototype = new BaseClass();
		//设置constructor
		ExtendClass.prototype.constructor = ExtendClass;
		
		var instance = new ExtendClass();
		instance.showMsg(); 		//ExtendClass::showMsg::ExtendClassName
		//相当于instance.__proto__.baseShowMsg() this指向instance
		instance.baseShowMsg(); 	//BaseClass::baseShowMsg::ExtendClassName
		
		ExtendClass.prototype.showMsg();					//BaseClass::showMsg::BaseClassName
		ExtendClass.prototype.showMsg.call(instance);		//BaseClass::showMsg::ExtendClassName
		
		//static方法调用,BaseClass.__proto__是Function.prototype
		//this指向function类型的BaseClass对象,
		show(BaseClass.__proto__ == Function.prototype);	//true	
		//static方法的this指向fuction本身,fuction名称本身是Function的实例
		BaseClass.showMsg();		//BaseClass::showMsg static name = undefined
		ExtendClass.showMsg();		//ExtendClass::showMsg static name = undefined
		//创建对象之后修改构造函数的原型对象(不是替换),指向的还是同一个原型对象,则所有修改前后创建的对象都指向修改后的原型对象。
		ExtendClass.prototype.baseShowMsg = function() { show("prototype::baseShowMsg"); };
		instance.baseShowMsg();		//prototype::baseShowMsg
		
		var str = "";
		for(var key in ExtendClass.prototype) {
			str += key;
			str += "=";
			str += ExtendClass.prototype[key];
			show(str);
			str = "";
		}
		//name=BaseClassName
		//showMsg=function() { show("BaseClass::showMsg::" + this.name); }
		//baseShowMsg=function() { show("prototype::baseShowMsg"); }
		//constructor=function ExtendClass() { this.name = "ExtendClassName"; this.showMsg = function () { show("ExtendClass::showMsg::" + this.name); }; }
		
		
		//创建对象之后替换构造函数的prototype,已创建的对象继续指向原来的prototype对象,此时修改前后的对象的__proto__不再是同一个对象。
		ExtendClass.prototype = new BaseClass();
		var instance1 = new ExtendClass();
		//替换原型对象
		ExtendClass.prototype = {id : "json", baseShowMsg : function() { show("json::baseShowMsg"); }};
		show(instance1.id);				//undefined
		instance1.baseShowMsg();		//BaseClass::baseShowMsg::ExtendClassName
		//instance2指向新的原型对象
		var instance2 = new ExtendClass();
		show(instance2.id);				//json
		instance2.baseShowMsg();		//json::baseShowMsg
		
		//对象独立于构造函数,构造函数完成了自己的主要工作(创建对象)以后可以删除。原型对象通过引用__proto__属性继续存在
		ExtendClass.prototype = new BaseClass();
		var instance3 = new ExtendClass();
		show(instance3.id);				//undefined
		//为原型对象增加属性
		ExtendClass.prototype.id = "new id";	
		ExtendClass.prototype.func = function() { show("new.func() invoked"); };
		show(instance3.id);				//new id
		instance3.func();				//new.func() invoked
			
		//instanceof操作符是和原型链一起工作的,而不是构造函数
		ExtendClass.prototype = new BaseClass();
		var instance4 = new ExtendClass();
		show(instance4 instanceof BaseClass);	//true
		ExtendClass.prototype.id = "new id";
		show(instance4 instanceof BaseClass);	//true
		ExtendClass.prototype = {id : "json", baseShowMsg : function() { show("json::baseShowMsg"); }};
		show(instance4 instanceof BaseClass);	//true
		//instance4是ExtendClass创建的对象,instanceof是比较prototype是否在同一个原型链上
		show(instance4 instanceof ExtendClass);	//false
		var instance5 = new ExtendClass();
		show(instance5 instanceof BaseClass);	//false
		
		//Object.prototype.hasOwnProperty(attr):判断一个对象是否包含自定义属性而不是原型链上的属性
		var foo = {
		    value : 42,
		    method : function() {}
		};
		show(foo.hasOwnProperty("value"));		//true
		show(foo.hasOwnProperty("method1"));	//false
		
		//JavaScript 不会保护 hasOwnProperty 被非法占用,因此如果一个对象碰巧存在这个属性,就需要使用外部的 hasOwnProperty 函数来获取正确的结果。
		show(Object.prototype.hasOwnProperty.call(foo, "method"));	//true

	// ]]>
	</script>
  </body>
</html>

相关推荐