js函数解读

虽然很早就接触js了,但是一直以来都学得不好,只有半桶水,基本只够简单应用。复杂的什么例如写js控件,修改js库源码就无能为力了。虽然不是什么前端工程师,但是经常用到,所以还是学好点吧。。。

 

对一些概念不清楚,写函数的时候也只是非常小心,然而还是有问题,于是就调试来调试去,效率非常低。这几天有点空闲。写了测试例子,一下子清楚多了。

 

this 的含义

a . 在js文件的最顶层 直接调用时:

//在js文件的最顶层

//alert(this);//[object Window]  为此“全局变量”window,
var thisTest=function asYouLike(x,y) {
	//alert(userManager.bbb);
	this.ma = x;// 相当于给Window增加属性---- 但这是不会成功的,因为Window属性只读,不可写
	this.mb = "MA"; 
	alert("thisTest call by globe object: this = "+this);//this 为调用modify函数的对象:[object Window]---为什么不是button?这是js的实现机制决定的
	alert("this.ma = "+this.ma);// 当使用new操作符的时候,this指向新建的对象!否则。。。因为之前window没定义名为ma的变量,所以undefined
	alert("this.mb = "+this.mb);//undefined
	alert("this.mc = "+this.mc);//undefined
}
thisTest();

 

 

b. 当把thisTest当做一个类( new+ 函数名+() )时:this所表示的意思会不同

// 几乎同样的代码
var thisTest=function asYouLike(x,y) {
	this.ma = x;
	this.mb = "MA"; 
	alert("thisTest call by a class object: this = "+this);//
	alert("this.ma = "+this.ma);// 当使用new操作符的时候,this指向新建的对象!==== undefined 因为没有传入x 
	alert("this.mb = "+this.mb);//"MA"
	alert("this.mc = "+this.mc);//undefined 因为它没定义
}
var tt = new thisTest();

 

函数

//可以这么调用
var testFunc = function(x,y,z) {
	this.name = x;
	this.age = y;
	testvar = z;
	alert("Hello boy!");
	alert("this:"+this+" x:"+x+" y:"+y+" z:"+z);
}
testFunc();
alert(testFunc);//

//也可以简单直接的这么调用:在这种情况下,testFunc为匿名函数返回值;匿名函数只能被调用一次
var testFunc2 = function(x,y,z) {
	this.name = x;
	this.age = y;
	testvar = z;
	alert("Hello boy!");
	alert("this:"+this+" x:"+x+" y:"+y+" z:"+z);
}();
alert(testFunc2);//undefined

 

 

 

 

 函数中变量的用法--作用域、读取的方式

//函数中变量的用法--作用域、读取的方式
var fa = " global var fa";
var fb = " global var fb";
var func = function () {
	var fa = 11;
	var ff = function(){
		alert(fa);//原型链方式读取:首先从当前函数func中读取,找不到则..最后从全局对象中读取
		alert(this.fa);//注意this在这里起的作用,他指向全局对象,所以直接从全局对象读取
		alert(this.fb);
	}
	ff();
}
//func.ff();//TypeError: f.ff is not a function
func();

 

 

对象/类

 

//对象/类
//函数 ------ 其实又可当做对象的构造函数
var Person = function(name,age){
	this.name = name;
	this.age = age;
	this.birthday = new Date();
	this.toString = function (){
		return "Person:name="+this.name+"/age="+this.age;
	};
}

var person = new Person("lk",26);
alert(person.age);


var globeFunc = function(x,y,z) {
 this.name = x;// 此处悄然改变了this(调用者) 的name值!!!
 this.mc = "MMCC";
 testvar = z;
 
 
 
 alert("this:"+this+" x:"+x+" y:"+y+" z:"+z);//this:Person:name=1/age=26 x:1 y:2 z:undefined
}
globeFunc.call(person,1,2);

 

//小结: 函数中this跟调用环境息息相关,谁调用了这个函数,this就是谁 
//小结: 对象中方法的 this ? 一般情况下就是所属的对象,但是,如果用apply/call来调用呢?

如果使用函数的call、apply来调用函数,则函数里面this的为传入的this参数,此时需要特别注意! 否则引起错误!!!

 

 

 

闭包:

闭包是一个比较难理解的概念,特别是对应初学者,难以真正理解,我曾经试着去理解,找了很多资料,看了很多文档,却对这个概念依然模糊,说不清道不明——当然一旦真正理解,则发现很简单了,像我现在这样;———— 所以说有些东西还是得自己亲自动手,做些小实验。所谓百读不如一练

 

//闭包
//非闭包的情况
var Car = function(speed,num,miles){
	var speed = speed;
	return{
		run:function(){
			alert("running");
		},
		start:function(){
			alert("start");
		},
		stop:function(){
			alert("stop");
		}
	}
}
//Car.run();// Car.run is not a function -- 此时Car还不是一个对象
var car = new Car();
car.run();//car还只是一个对象,当然可以这么调用
alert(car.speed);// undefined
//无法访问闭包的属性,因为闭包的属性相当于被限制为private了
//speed 并不属于调用者的属性,此时可以当做闭包的属性了

//闭包的情况
var Dog = function(name,age,height){
	var name = name;
	return{
		bart:function(){
			alert("wong! wong! wong!!!");
		},
		eat:function(){
			alert("eat");
		},
		sleep:function(){
			alert("sleep");
		}
	}
}()
Dog.bart();// 此时Dog已经是一个对象 ---- 建立一个函数,然后执行它,返回return语句后面的对象!

// 所以说闭包实现的关键是 
1 创建一个函数并立即执行它,使用()运算符
2 函数中的return语句中返回一个对象--- 否则函数值就是undefined

 

——————

// 要立即,return 返回{} 就是一个对象!—— 其实稍微想想也就知道,只是一直就没这么想过。。。
// 否则如果没有return,建立一个函数,然后执行它 --- 返回undefined

 

var Man = function(name,age){
	this.name = name;
	this.age = age;
	this.mc = "MMCC";
	this.speak = function (){
		alert("Man:name="+this.name+"/age="+this.age);
	};
}();
//Man.speak();// Man is undefined--- 这种方式却不行

var Woman = function(name,age){
	this.name = name;
	this.age = age;
	this.mc = "MMCC";
	this.speak = function (){
		alert("Woman:name="+this.name+"/age="+this.age);
	};
	return{
		run:function(){
			alert("a woman is running");
		}
	}
}();
//Woman.run();// 现在又可行了!
//Woman.speak();//Man.speak is not a function 现在报这个错了,不是Woman is undefined

 

 

 

函数的嵌套

// 函数的嵌套
var Nest = function(name,age){
	this.name = name;
	this.age = age;// 不能写成 age = age;?这当然是不行的
	this.mc = "MMCC";
	var th = this;
	this.speak = function (){
		//alert(th);[Object]
		alert(this);// 此处的this 指的是new出来的Nest对象
		alert("Nest:name="+this.name+"/age="+this.th);
		th.speakAlout = function (){// 如果不加this, th 从哪里获取呢?从当前对象,找不到就是全局对象
			alert("a Nest is running");
		}
		obj.objFunc = function (){
			alert("==objFunc==");
		}
//		th.speak.speakAlout = function (){// 如果不加this, th 从哪里获取呢?
//			alert("a Nest is speakAlout");
//		}
		nestFunction = function (){//这样的嵌套函数是怎么调用的呢??
			alert("a Nest function  is running/this is:"+this);//此时的this为[object Window] ?怪怪的
		}
		//nestFunction();//这样调用
		this.toString = function (){
			return "next.speak";
		}
	};
	this.toString = function (){
		return "next.object";
	}
	var fasf = function() {//可以写这种函数/属性,但实际上,它是private的,外面无法调用
		alert(1231312);
	}
	fasf();
//	return{
//		run:function(){
//			alert("a woman is running");
//		}
//	}
};
var nest = new Nest("lk","123");//TypeError: Nest is not a constructor
nest.speak();// 因为speakAlout是在speak定义的,所以要先执行speak(),才能找到speakAlout
nest.speakAlout();

alert("this.nestFunction=="+this.nestFunction);// 在nest.speak()之后nestFunction已经变成了一个全局函数!
alert(nest.speak.speakAlout);//undefined 否则,直接显示函数内容

nest.fasf();//nest.fasf is not a function
nest.speak.speakAlout();//TypeError: nest.speak.speakAlout is not a function

 

 

 注意:在嵌套的函数里面,this总是对应window(稍微有点疑问)

 

//闭包中嵌套呢?(闭包的-closure)
var closure_nest = function(name,age){
	var f = function() {//可以写这种函数/属性,但实际上,它是private的,外面无法调用
		alert("im a private function ! ");
		var f_nest = function() {//可以写这种函数/属性,但实际上,它是private nest的,外面更加无法调用
			alert("im a private nest function ! ");
		}
		this.f_nest_g = function() {//可以写这种函数/属性,但实际上,它是private nest的,外面更加无法调用
			alert("im NOT a private nest function !im globe ");
		}
	}
	//alert(this);// [object Window]
	return {
		ff:function() {//可以写这种函数/属性,但实际上,它是private的,外面无法调用
			//alert("im a private function ! ");
			ff_nest = function() {//可以写这种函数/属性,但实际上,它是private nest的,外面更加无法调用
				alert("im a private nest function ! ");
			}
			this.ff_nest_g = function() {//可以写这种函数/属性,它是属于的return返回的对象的,通过闭包方式调用
				alert("im NOT a private nest function !im closure ");
				ff_nest_nest = function() {//可以写这种函数/属性,似乎可以永远继续嵌套!
//					alert("im a private nest nest function ! this aaa:"+this);//此处的this对应window !
					ffasf = function() {
						alert(987923233+""+this);// N里面嵌套,此处永远的this对应window 
					}();
				}
				ff_nest_nest();
			}
			this.toString = function () {
				return " closure_nest ff this.toString  ";
			}
			toString = function () {// 相当于重写了 window 的toString 函数
				return " closure_nest ff  nested  toString 相当于window的toString  !";
			}
			wirld = function () {
				ff_nest123 = function() {
					alert("im a private nest nest function ! ");
					alert(this);// 此处的this对应window !
//					this.fffff();
				}
				ff_nest123();
				return " closure_nest ff  nested  toString ";
			}
			fffff = function(){
				alert(" fffff ! ");
			}
			wirld();
//			ff_nest();
//			alert(this);// 此处的this 又是不同含义!// 调用this.toString
		}
	}
	// return {}后面的语句都不会执行
	alert(4444);
	ff_nest();
	toString = function () {
		return (" closure_nest ");
	}
}();

//ff_nest_g();// ReferenceError: ff_nest_g is not defined

//closure_nest.ff_nest();// undefined
closure_nest.ff();
closure_nest.ff_nest_g();//在ff之后,也能正常调用 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值