zoukankan      html  css  js  c++  java
  • JavaScript的"类"

      1. 基本创建“类”方式

    var Class = function(){
    	var klass = function(){
    		this.init.apply(this, arguments);
    	};
    	klass.prototype.init = function(){};
    	return klass;
    };
    
    var Person = new Class();
    Person.prototype.init = function(){
    	// 基于Person 的实例做初始化
    };
    
    Person.find = function(id){ /*...*/ };
    Person.prototype.breath = function(){ /*...*/ };
    Person.fn = Person.prototype;
    Person.fn.run = function(){ /*...*/ };
    
    // 用法
    var person = new Person();
    person.find(1);
    person.breath();
    person.run();
    

      2. 分辨类的静态属性和实例的属性

    var Class = function() {
    	var klass = function() {
    		this.init.apply(this, arguments);
    	};
    	klass.prototype.init = function() {};
    	//定义 prototype 的别名
    	klass.fn = klass.prototype;
    	// 定义类的别名
    	klass.fn.parent = klass;
    	// 给类添加属性
    	klass.extend = function(obj) {
    		var extended = obj.extended;
    		for (var i in obj) {
    			klass[i] = obj[i];
    		}
    		if (extended) extended(klass);
    	};
    	// 给实例添加属性
    	klass.include = function(obj) {
    		var included = obj.included;
    		for (var i in obj) {
    			klass.fn[i] = obj[i];
    		}
    		if (included) included(klass);
    	};
    	return klass;
    };
    
    var Person = new Class();
    // 添加静态属性
    Person.extend({
    	find: function(id) { /* ... */ },
    	exists: function(id) { /* ... */ }
    });
    //添加实例属性
    Person.include({
    	save: function(id) { /* ... */ },
    	destroy: function(id) { /* ... */ }
    });
    
    var person = new Person();
    person.save();  

       在类之间共享通用的属性

    var ORMModule = {
    	save: function(){
    		// 共享的函数
    	}
    };
    var Person = new Class();
    var Asset = new Class();
    
    Person.include(ORMModule);
    Asset.include(ORMModule);
    

       JavaScript 是基于原型的编程语言,原型用来区别类和实例,这里提到一个概念:原型对象(prototypical object)。原型是一个“模板”对象,它上面的属性被用做初始化一个新对象。任何对象都可以作为另一个对象的原型对象,以此来共享属性。

      当读取一个对象的属性时,JavaScript 首先会在本地对象中查找这个属性,如果没有找到,JavaScript 开始在对象的原型中查找,若还未找到还会继续查找原型的原型,直到查找到Object.prototype。如果找到这个属性,则返回这个值,否则返回undefined。

      为了让子类继承父类的属性,首先需要定义一个构造函数。然后需要将父类的新实例赋值给构造函数的原型。

    var Animal = function(){};
    Animal.prototype.breath = function(){
    	console.log('breath');
    };
    
    var Dog = function(){};
    
    // Dog 继承了Animal
    Dog.prototype = new Animal();
    Dog.prototype.wag = function(){
    	console.log('wag tail');
    };
    
    var dog = new Dog();
    dog.wag();
    dog.breath(); // 继承的属性
    

       3. 添加继承,通过传入一个可选的父类来创建新类

    var Class = function(parent) {
    	var klass = function() {
    		this.init.apply(this, arguments);
    	};
    
    	// 改变klass 的原型  只有实例的属性才会被继承,而非类的属性
    	if (parent) {
    		var subclass = function() { };
    		subclass.prototype = parent.prototype;
    		klass.prototype = new subclass;
    	};
    
    	klass.prototype.init = function() {};
    	//定义 prototype 的别名
    	klass.fn = klass.prototype;
    	// 定义类的别名
    	klass.fn.parent = klass;
    	klass._super = klass.__proto__;
    
    	// 给类添加属性
    	klass.extend = function(obj) {
    		var extended = obj.extended;
    		for (var i in obj) {
    			klass[i] = obj[i];
    		}
    		if (extended) extended(klass);
    	};
    	// 给实例添加属性
    	klass.include = function(obj) {
    		var included = obj.included;
    		for (var i in obj) {
    			klass.fn[i] = obj[i];
    		}
    		if (included) included(klass);
    	};
    	return klass;
    };
    
    var Animal = new Class();
    Animal.include({
    	breath: function(){
    		console.log('breath');
    	}
    });
    var Cat = new Class(Animal);
    var tommy = new Cat();
    tommy.breath();  
    

       apply() 函数有两个参数:第1 个参数是上下文对象,第2 个参数是参数组成的数组。如果上下文对象是null,则使用全局对象代替。

       call() 函数的行为和apply() 函数类似,只是使用方法不一样。call() 的第1 个参数是上下文对象,后续是实际传入的参数序列。

    functionName.apply(this, [1, 2, 3]);
    functionName.call(this, 1, 2, 3);
    

       使用apply() 和call() 来更改上下文对象

    //为了访问原始上下文对象,可以将this 的值存入一个局部变量中。
    var clicky = {
    	wasClicked: function(){ },
    	addListeners: function(){
    		var self = this;
    		$('.clicky').click(function(){
    			self.wasClicked();
    		});
    	}
    };
    clicky.addListeners();
    
    //可以使用apply 来将这段代码变得更干净一些,通过将回调包装在另外一个匿名函数中,来保持原始的上下文
    var proxy = function(func, thisObject){
    	return function(){
    		return func.apply(thisObject, arguments);
    	};
    };
    
    var clicky = {
    	wasClicked: function(){ },
    	addListeners: function(){
    		var self = this;
    		$('.clicky').click(proxy(this.wasClicked, this));
    	}
    };
    clicky.addListeners();
    

       4. 控制“类”的作用域 在类和实例中都添加proxy函数

    var Class = function(parent){
    	var klass = function(){
    		this.init.apply(this,arguments);
    	}
    	//继承
    	if (parent) {
    		var subclass = function() { };
    		subclass.prototype = parent.prototype;
    		klass.prototype = new subclass();
    	}
    	
    	klass.prototype.init = function(){};
    	klass.fn = klass.prototype;
    	klass.fn.parent = klass;
    	klass._super = klass.__proto__;
    	
    	//类 静态属性
    	klass.extend = function(obj){
    		var extended = obj.extended;
    		for(var i in obj){
    			klass[i] = obj[i];
    		}
    		if(extended) extended(klass);
    	}
    	//类 实例属性
    	klass.include = function(obj){
    		var included = obj.included;
    		for(var i in obj){
    			klass.fn[i] = obj[i];
    		}
    		if(included) included(klass);
    	}
    	//类 作用域
    	klass.proxy = function(func){
    		var self = this;
    		return(function(){
    			return func.apply(self, arguments);
    		});
    	}
    	klass.fn.proxy = klass.proxy;
    	
    	return klass;
    }
    
    var Button = new Class();
    Button.include({
    	init: function(element){
    		this.element = jQuery(element);
    		// 代理了这个click 函数
    		this.element.click(this.proxy(this.click));
    	},
    	click: function(){ }
    });
    
  • 相关阅读:
    nodeJS 菜鸟入门
    Chrome 鲜为人知的秘籍(内部协议)&&Chrome功能指令大全
    前端工作面试问题
    ECharts模块化使用5分钟上手
    AppCan 之初体验
    Phonegap 环境配置
    【位运算】判断一个数是否为2的n次方
    【位运算】移位操作实现乘法运算
    O(1)时间复杂度求栈中最小元素
    Java Socket UDP编程
  • 原文地址:https://www.cnblogs.com/eyeear/p/4649666.html
Copyright © 2011-2022 走看看