欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js面向对象3--更简单的原型模式已经带来的问题以及解决办法

程序员文章站 2022-07-06 19:56:33
...
<%@ page language="java" contentType="text/html;
charset=UTF-8"  pageEncoding="UTF-8"%>
<html>
<head>
<script type="text/javascript">
    /*
          更简单的原型模式以及由此带来的问题:
          在本人博客“ js面向对象2--js中工厂模式的演化(重要,详细)”中的原型模式
          是最基本也最正确的原型模式的用法,但是每次都用Person.prototype.属性名称
          来个原型模式添加方法和属性未免太过繁琐。
          为了减少不必要的输入,也为了从视觉上更好的封装原型的功能,更常见的做法是用一个
          包含所有属性和方法的对象资源面来重写这个原型对象,如下:
    */
    //正常的原型写法:
    function Person(){}
    Person.prototype.name = "chenchaoyang";
    Person.prototype.age = 12;
    Person.prototype.job = "Software enginner";
    Person.prototype.sayName = function (){
    	alert(this.name);
    }
    
    var person1 = new Person();
    
    //简单的原型写法
    function Person(){}
    Person.prototype = {
    		name:"chenchaoyang",
    		age:"12",
    		job:"Software enginner",
    		sayName:function(){
    			console.log(this.name);
    		}
    }
    var person2 = new Person();
    
    function onloadFunction()
    {
        console.log(person1.constructor); //Person()
        console.log(person2.constructor); //Object()
    }
    
    /*
        在上面代码,我们将Person.prototype 设置为等于一个以对象字面量形式创建的
        新对象,最终结果相同,但有一个例外,constructor属性不再指向Person了。
        原因:
       每创建一个函数,就会同事创建它的prototype对象,这个对象也会自动获得constructor
       属性。而我们在这里使用的语法,本质上完全重写了默认的prototype对象,因此constructor
       属性也就变成了新对象的constructor属性(指向Object构造函数),不再指向Person函数,
       此时尽管instanceof操作符还能返回正确的结果,但通过constructor已经无法确定对象
       的类型了。
       
       如果在编程过程中,一个对象的constructor值很重要,可以像下面这样的方法去改写:
    */
    function Person(){}
    Person.prototype = {
    		constructor : Person,  //人为的制定原型对象的构造函数指向
    		name : "chenchaoyang",
    		age :13,
    		sayName : function(){
    			alert(this.name);
    		}
             
    }
    
    /*
        注意:以上面的方式重设constructor属性会导致它[[Enumerable]]特性被设置为true。默认
        情况下,原声constructor属性是不可枚举的,因此如果你使用兼容EcmAScript5的JavaScript
        引擎,可以试一试Object.defineProperty().如下:
        function Person(){}
        Person.prototype = {
        		name : "chenchaoyang",
        		age : 12,
        		job : "Soft Enginner",
        		sayName : function(){
        			console.log(this.name);
        		}
         //重写原型对象的构造函数,只适用于ECMAScript5兼容的浏览器
         Object.defineProperty(Person.prototype,"constructor",{
        	 enumerable:false,
        	 value:Person
         })
        }
        
        此种模式堪称完美。。。。。。。。。Over
    */
</script>

</head>

<body onload="onloadFunction();">
</body>
</html>