首页 > 代码库 > javascript中this的详细使用

javascript中this的详细使用

	document.write("<br/>**************一.指代当前对象**********************");
	function print(str){
		document.write(str+"<br/>");
	};
	/*
		javascript里面的this可谓是所有语言里最让人费解的了,学习国java或者php的人
		在学习javascript的时候会觉得非常莫名其妙,因为它不是面向对象的.而且它的复
		杂度也是贯穿javascript函数式编程的核心之一.
		记住最重要的一句话.如下:
		javascript中的this可能指代当前对象,也可能不是
		其简单分析如下:
		一.指代当前对象
		1.指代当前对象
			如:在表单操作中使用this来指代当前的dom对象
		2.指代当前构造函数实例
		3.指代当前对象直接量
		4.指代全局对象
		二.指代当前作用域
	*/

	//1.指代当前对象
	var obj = new Object();
	obj.name = "felayman1";
	obj.getName = function(){
		return this.name;
	};
	print(obj.getName());
	//2.指代当前构造函数实例
	function Template(){
		this.name = "felayman2";
	}
	var instanll = new Template();
	print(instanll.name);//指向构造函数的实例
	// 3.指代当前对象直接量
	var object = {
		"name":"felayman3",
		"age":22,
		getName:function(){
			return this.name;
		},
		getAge:function(){
			return this.age
		}
	};
	print(object.getName()+object.getAge());
	// 4.指代全局对象
	print(this);
	print("*******************二.指代当前作用域********************************");
	var func  = function(){
		print(this);
	};
	func();//会打印出object Window
	print((typeof func));//此时是function
	print((typeof func()));//window和undefined 因为函数调用完成后不属于某个类型
	document.write("***********对象************<br/>");
	print(new func());//会打印出object
	print(typeof(new func()));//这里是两个object,因为有了具体的引用对象
	/*
		分析:
			当直接调用函数的时候,浏览器会直接把该函数解析成一个普通的函数调用,去执
			行函数内部的代码,或许有人在这里会觉得this就指向func函数,或者是它的一个
			指针或者句柄,很可惜都不是,这与javascript引擎的内存模型有关,我们都知道
			javascript是解释性语言,而非编译型的,因此浏览器遇到的所有javascript代码
			都会按照特定的步骤或者顺序来执行代码,引擎在加载一个脚本后,会首先提取那
			些由var声明的变量或者函数(只是全局环境下的),把提取到的变量保存在一个临时
			表中,我们可以理解成一块内存区域,然后才会去逐行解析代码,在解析的过程中,碰
			到函数调用会去临时表中寻找对应的函数,当然引擎是很智能的,能判断出要执行的
			是普通的函数调用,还是对象的创建(只针对此例子),因此,在javascript我们对于
			函数和对象还是分开的,其实可以这么理解,函数就是类模板,而对象就是类模板的
			一次实例.类模板的类型属于函数,而对象的类型属于object.
			而正是this的这种特性,造就了this在函数闭包中的强大功能.如下例子
	*/
	print("********************************************");
	function f(){
		return this;
	}
	//定义一个嵌套的字面量
	var obj = {
		"name":"对象0bj",
		"getThis":f(),
		"obj1":{
			"name":"对象obj1",
			"getThis":f(),
			"obj2":{
				"name":"对象obj2",
				"getThis":f()
			}
		}
	};
	print(obj.obj1.obj2.name);//表明可以获取到obj对象属性
	//将Obj2对象的函数指向过渡给person
	print(obj.getThis);//输出window
	print(obj.obj1.getThis);//输出window
	print(obj.obj1.obj2.getThis);//输出window
	/*
		对于上面的结果,如果我们不给明显对比的例子,可能我们很难理解我想要表达的
		的是什么,在此,我先不解释上面的例子,我再给出下面的一个例子,产生对比来比较
		两个例子的异同来分析
	*/
	print("********************************************");
	function ff(){
		return this;
	}
	var  object = {
		"name":"对象0bject",
		"getThis":ff,
		"object1":{
			"name":"对象0bject1",
			"getThis":ff,
			"object2":{
				"name":"对象0bject",
				"getThis":ff
			}
		}
	};
	print(obj.obj1.obj2.name);//表明可以获取到obj对象属性
	//将Obj2对象的函数指向过渡给person
	print(object.getThis());//输出object
	print(object.object1.getThis());//输出object
	print(object.object1.object2.getThis());//输出object
	/*
		这样以来,结果就出来了,如果不细心的读者还没看出两个例子有什么区别
		的确,区别不是很大,但是其结果却截然不同
		我们来分析一下:
		在第一个例子中,我们在为字面量对象添加方法的时候,请注意,我写的是带
		括号的,带括号是什么含义呢?函数调用,这里我们要明白一个道理,字面量对
		象不是函数,它在对象确定的时候,内部所有属性和方法都会存入到该对象的
		内存块中,其方法内的可执行代码会先被解析器解析好,只保存最终结果,因此
		上述的getThis方法指向的是一个函数调用,因此只会保留该函数的最终结果
		而这个最终结果所返回的结果恰好是我们最开始例子的说明,其返回值是一个
		window全局对象.因此导致字面量对象以及其属性对象的getThis都指向该window
		对象.
		而在第二个例子中,我们的getThis只是复制ff函数的一个引用,而不是指向ff函数
		的的结果,因为此时该函数原型被提取到临时表中,并没有被浏览器解析,而是等到
		调用该函数的时候才会去解析它,当js引擎遇到object.getThis()的是才会去执行
		相应的代码,而此时的环境已经发生变化了,再执行ff函数的时候,返回的this就会
		指向当前包含它环境的对象,因此会返回不同的object,而这个特性正是闭包的强大
		点,我们可以构建不同层次的闭包函数来改变this所指向的对象或者环境,以此来搭
		建更加复杂的函数模型,这就是后面我们要说的函数式编程.
	*/