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之后,也能正常调用