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

js函数解读

程序员文章站 2022-06-07 19:14:41
...

虽然很早就接触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之后,也能正常调用