一种基于JS原型链的类的构造与派生。原创
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一种基于JS原型链的类的构造与派生。原创相关的知识,希望对你有一定的参考价值。
转载请注明出处
2016.7.5 by Totooria Hyperion
// 初始化prototype和静态方法 function initClass(constructor,_proto) { // 配置prototype for(var key in _proto) { constructor.prototype[key] = _proto[key]; if(typeof _proto[key] == "function") { Object.defineProperty(constructor.prototype,key,{"enumerable":false}); } } // 为Class扩展方法/属性的函数 constructor.extend = function(obj) { for(var key in obj) { if(this.hasOwnProperty(key)) { Error("this property already exist"); } else { this.prototype[key] = obj[key]; if(typeof obj[key] == "function") { Object.defineProperty(this.prototype,key,{"enumerable":false}); } } } } // 为Class删除方法/属性的函数 constructor.delete = function(array) { array.forEach(function(item){ delete this.prototype[item]; }); } // 为Class重写方法/属性的函数 constructor.rewrite = function(key,value) { this.prototype[key] = value; if(typeof this.prototype[key] == "function") { Object.defineProperty(this.prototype,key,{"enumerable":false}); } } } // 声明一个类,如果有基类superType,则生成其子类 function Class(name,constructor,_proto,superType){ // 适配浏览器和非浏览器(nodejs等) var Global = Global || window; if(superType) { // 创建一个Class并进行初始化和父类初始化(组合继承:原型链继承+借用构造函数) Global[name] = function (obj) { var arg = obj ? obj : {}; superType.call(this,arg); constructor.call(this,arg); }; Global[name].name = name; Object.defineProperty(Global[name],"name",{"value":name,"enumerable":false,"writable":false}); // 寄生继承 var pro = Object.create(superType.prototype); pro["constructor"] = Global[name]; Global[name].prototype = pro; // 使构造函数不可被for-in遍历,排除干扰 Object.defineProperty(Global[name].prototype,"constructor",{"enumerable":false}); // 初始化prototype和静态方法 initClass(Global[name],_proto); } else { // 创建一个Class Global[name] = constructor; Object.defineProperty(Global[name],"name",{"value":name,"enumerable":false,"writable":false}); // 初始化prototype和静态方法 initClass(Global[name],_proto); } }
测试代码如下:
Class("Person",function (obj){ obj.name ? this.name = obj.name : obj.name ; },{ "name":"Unnamed", "gender":"Male", "sayHello":function(){ console.log(this.name + ":Hello"); } }); Class("PersonWithAge",function(obj){ obj.age ? this.age = obj.age : obj.age; },{ "age":"1", "sayGoodbye":function(){ console.log(this.name + ":Goodbye"); } },Person); Class("PersonMaria",function(obj){ // obj.age ? this.age = obj.age : obj.age; },{ "name":"Maria", "sayGoodbye":function(){ console.log(this.name + ":Goodbye"); } },Person); Class("PersonMariaWithAge",function(obj){ obj.age ? this.age = obj.age : obj.age; },{ "name":"Maria", "age":"1", "sayGoodbye":function(){ console.log(this.name + ":Goodbye"); } },Person); var jack = new Person({"name":"Jack"}); var potterWithAge = new PersonWithAge({"name":"Potter","age":"18"}); var maria = new PersonMaria(); var mariaWithAge = new PersonMariaWithAge({"age":"16"}); console.log(jack); //console.log(jack.constructor); console.log(jack instanceof Person); console.log(potterWithAge); //console.log(potterWithAge.constructor); console.log(potterWithAge instanceof Person); console.log(potterWithAge instanceof PersonWithAge); console.log(maria); //console.log(maria.constructor); console.log(maria instanceof Person); console.log(maria instanceof PersonMaria); console.log(mariaWithAge); //console.log(mariaWithAge.constructor); console.log(mariaWithAge instanceof Person); console.log(mariaWithAge instanceof PersonMariaWithAge); Class("PersonWithAgeAndHeight",function(obj){ obj.height ? this.height = obj.height : obj.height; },{ "height":"180", "sayHeight":function(){ console.log(this.name + ":Height is " + this.height); } },PersonWithAge); var johnWithAgeAndHeight = new PersonWithAgeAndHeight({"name":"John","height":"160"}); console.log(johnWithAgeAndHeight); console.log(johnWithAgeAndHeight instanceof Person); console.log(johnWithAgeAndHeight instanceof PersonWithAge); console.log(johnWithAgeAndHeight instanceof PersonWithAgeAndHeight); function getInfo(obj){var str = "<br>{<br>";for(key in obj) {str += " " + key + ‘:"‘ + obj[key] + ‘",<br>‘};str.slice(0,-5);str+="}";return str;} document.write(getInfo(jack) + "<br>"); //console.log(jack.constructor); document.write("jack instanceof Person : " + (jack instanceof Person) + "<br>"); document.write(getInfo(potterWithAge) + "<br>"); //console.log(potterWithAge.constructor); document.write("potterWithAge instanceof Person : " + (potterWithAge instanceof Person) + "<br>"); document.write("potterWithAge instanceof PersonWithAge : " + (potterWithAge instanceof PersonWithAge) + "<br>"); document.write(getInfo(maria) + "<br>"); //console.log(maria.constructor); document.write("maria instanceof Person : " + (maria instanceof Person) + "<br>"); document.write("maria instanceof PersonMaria : " + (maria instanceof PersonMaria) + "<br>"); document.write(getInfo(mariaWithAge) + "<br>"); //console.log(mariaWithAge.constructor); document.write("mariaWithAge instanceof Person : " + (mariaWithAge instanceof Person) + "<br>"); document.write("mariaWithAge instanceof PersonMariaWithAge : " + (mariaWithAge instanceof PersonMariaWithAge) + "<br>"); document.write(getInfo(johnWithAgeAndHeight) + "<br>"); document.write("johnWithAgeAndHeight instanceof Person : " + (johnWithAgeAndHeight instanceof Person) + "<br>"); document.write("johnWithAgeAndHeight instanceof PersonWithAge : " + (johnWithAgeAndHeight instanceof PersonWithAge) + "<br>"); document.write("johnWithAgeAndHeight instanceof PersonWithAgeAndHeight : " + (johnWithAgeAndHeight instanceof PersonWithAgeAndHeight) + "<br>"); document.write("johnWithAgeAndHeight instanceof PersonMaria : " + (johnWithAgeAndHeight instanceof PersonMaria) + "<br>");
测试结果如下(浏览器窗口输出):
{ name:"Jack", gender:"Male", } jack instanceof Person : true { name:"Potter", age:"18", gender:"Male", } potterWithAge instanceof Person : true potterWithAge instanceof PersonWithAge : true { name:"Maria", gender:"Male", } maria instanceof Person : true maria instanceof PersonMaria : true { age:"16", name:"Maria", gender:"Male", } mariaWithAge instanceof Person : true mariaWithAge instanceof PersonMariaWithAge : true { name:"John", height:"160", age:"1", gender:"Male", } johnWithAgeAndHeight instanceof Person : true johnWithAgeAndHeight instanceof PersonWithAge : true johnWithAgeAndHeight instanceof PersonWithAgeAndHeight : true johnWithAgeAndHeight instanceof PersonMaria : false
以上是关于一种基于JS原型链的类的构造与派生。原创的主要内容,如果未能解决你的问题,请参考以下文章