Javascript基础知识——匿名函数和闭包(2)
js中的匿名函数

js中的匿名函数匿名函数顾名思义指的是没有名字的函数,在实际开发中使⽤的频率⾮常⾼!也是学好JS的重点。
匿名函数:没有实际名字的函数。
⾸先我们声明⼀个普通函数://声明⼀个普通函数,函数的名字叫fnfunction fn(){console.log("张培跃");}然后将函数的名字去掉即是匿名函数://匿名函数,咦,运⾏时,你会发现报错啦!function (){console.log("张培跃");}到此,你会发现单独运⾏⼀个匿名函数,由于不符合语法要求,报错啦!解决⽅法只需要给匿名函数包裹⼀个括号即可://匿名函数在其它应⽤场景括号可以省略(function (){//由于没有执⾏该匿名函数,所以不会执⾏匿名函数体内的语句。
console.log("张培跃");})如果需要执⾏匿名函数,在匿名函数后⾯加上⼀个括号即可⽴即执⾏!(function (){//此时会输出张培跃console.log("张培跃");})()倘若需要传值,直接将参数写到括号内即可:(function (str){//此时会输出张培跃好帅!console.log("张培跃"+str);})("好帅!")匿名函数的应⽤场景1、事件<input type="button" value="点我啊!" id="sub"><script>//获得按钮元素var sub=document.querySelector("#sub");//给按钮增加点击事件。
sub.onclick=function(){alert("当点击按钮时会执⾏到我哦!");}</script>2、对象var obj={name:"张培跃",age:18,fn:function(){return "我叫"++"今年"+this.age+"岁了!";}};console.log(obj.fn());//我叫张培跃今年18岁了!3、函数表达式//将匿名函数赋值给变量fn。
javaScriptFunction(函数)闭包匿名函数this对象

javaScriptFunction(函数)闭包匿名函数this对象1. Function函数接受的参数类型、个数没有限定。
参数在内部是⽤数组arguments来存储的。
因此函数没有重载。
可以提供arguments【i】来表⽰传⼊的参数4.1创建使⽤函数声明和函数表达式创建,也可以使⽤Function()构造函数Function sum(num1,num2){函数声明}Var sum = function(num1,num2){函数表达式}解析器会率先读取函数声明,并使其在执⾏任何代码之前可⽤;因为在代码执⾏之前,解析器就已经通过⼀个名为函数声明提升的过程,读取并将函数声明添加到执⾏环境,js引擎在第⼀遍会声明函数并将它们放到源代码树的顶部。
函数表达式须等到解析器执⾏到它所在代码⾏,才会真正被解析。
4.2函数内部属性Arguments指代参数Callee:arguments.callee指代拥有这个arguments对象的函数。
在递归调⽤时,⾮常有⽤。
Caller:保存着调⽤当前函数的函数的引⽤Function outer(){Inner();}Function inner(){Alert(inner.caller);//警告框中显⽰outer()函数的源代码,等价于arguments.callee.caller}This:this引⽤的是函数据以执⾏的环境对象。
4.3 call()和apply()扩⼤函数赖以运⾏的作⽤域每个函数都包含这两个⾮继承⽽来的⽅法。
这两个⽅法⽤途都是在特定的作⽤域⾥调⽤函数,实际上是设置函数体内的this值。
Apply()接受2个参数,⼀个是其中函数运⾏的作⽤域,另⼀个是参数数组Call()接受多个参数,⼀个是其中函数运⾏的作⽤域,其他是传递给函数的参数必须逐个列举出来Window.color = “red”;Var o = {Color:”blue”};Function sayColor(){Alert(this.color);}sayColor(); //redsayColor.call(window); //redsayColor.call(this); //redsayColor(o); //blue4.4java与js创建函数Java是:修饰符返回类型函数名(参数类型参数名){函数体}Js是:函数声明和函数表达式函数声明:function 函数名(参数名){函数体}函数表达式:var 函数名 = function(参数名){函数体}4.5匿名函数在function后⾯没有跟函数名的函数称为匿名函数。
详解JavaScript匿名函数和闭包

详解JavaScript匿名函数和闭包概述在JavaScript前端开发中,函数与对其状态即词法环境(lexical environment)的引⽤共同构成闭包(closure)。
也就是说,闭包可以让你从内部函数访问外部函数作⽤域。
在JavaScript,函数在每次创建时⽣成闭包。
匿名函数和闭包可以放在⼀起学习,可以加深理解。
本⽂主要通过⼀些简单的⼩例⼦,简述匿名函数和闭包的常见⽤法,仅供学习分享使⽤,如有不⾜之处,还请指正。
普通函数普通函数由fucntion关键字,函数名,() 和⼀对{} 组成,如下所⽰:function box(){return 'Hex';}alert(box());匿名函数顾名思义,匿名函数就是没有实际名字的函数。
单独的匿名函数⽆法运⾏,如下所⽰:function (){return 'Hex';}//以上,会报错:缺少标识符如何解决匿名函数不能执⾏的问题呢?有如下⼏种⽅法:1. 把匿名函数赋值给变量,如下所⽰://把匿名函数赋值给变量var box=function(){return 'Hex';}alert(box());2. 通过⾃我执⾏来调⽤函数,格式如下:(匿名函数)()(function(){alert('Hex');})();3. 把匿名函数⾃我执⾏的返回值赋值给变量,如下所⽰:var box=(function(){return 'Hex';})();alert(box);//注意:此处不带括弧4. 或者省去变量,如下所⽰:alert((function() {return 'Hex';})());⾃我执⾏匿名函数如何传递参数呢?如下所⽰:(function(age) {alert('Hex--' + age);})(30);闭包(closure)闭包是由函数以及创建该函数的词法环境组合⽽成。
JavaScript匿名函数(anonymousfunction)与闭包(closure)

JavaScript匿名函数(anonymousfunction)与闭包(closure)引⼊匿名函数闭包变量作⽤域函数外部访问函数内部的局部变量⽤闭包实现私有成员引⼊闭包是⽤匿名函数来实现。
闭包就是⼀个受到保护的变量空间,由内嵌函数⽣成。
“保护变量”的思想在⼏乎所有的编程语⾔中都能看到。
先看下 JavaScript 作⽤域:JavaScript 具有函数级的作⽤域。
这意味着,不能在函数外部访问定义在函数内部的变量。
JavaScript 的作⽤域⼜是词法性质的(lexically scoped)。
这意味着,函数运⾏在定义它的作⽤域中,⽽不是在调⽤它的作⽤域中。
这是 JavaScript 的⼀⼤特⾊,将在后⾯说明。
把这两个因素结合在⼀起,就能通过把变量包裹在匿名函数中⽽对其加以保护。
你可以这样创建类的私有变量:var baz;(function() {var foo = 10;var bar = 2;baz = function() {return foo * bar;};})();baz();尽管在匿名函数外执⾏,但 baz 仍然可以访问 foo 和 bar。
说明:1,第 1 ⾏,baz 是全局变量;2,第 3 ~第 9 ⾏,定义⼀个匿名函数;3,第 4 和 5 ⾏,foo 和 bar 是匿名函数内的局部变量;第 6 ~ 8 ⾏,在匿名函数内定义⼀个匿名函数,并将其赋值给全局变量 baz;4,第 10 ⾏,调⽤ baz。
若改成 "alert(baz());",将显⽰ 20;5,按理说,在匿名函数外不能访问 foo 和 bar,但是现在可以。
在说明闭包前,先了解⼀下匿名函数。
匿名函数匿名函数是指那些⽆需定义函数名的函数。
匿名函数与 Lambda 表达式(拉姆达表达式)是⼀回事。
唯⼀的不同——语法形式不同。
Lambda 表达式更进⼀步。
本质上,它们的作⽤都是:产⽣⽅法——内联⽅法,也就是说,省去函数定义,直接写函数体。
js比较难理解的知识点 知乎

js比较难理解的知识点知乎以js比较难理解的知识点JavaScript作为一门非常灵活和强大的编程语言,有一些概念和知识点对于初学者来说可能会比较难以理解。
本文将介绍一些常见的js知识点,帮助读者更好地理解和掌握这门语言。
1. 闭包(Closures)闭包是JavaScript中非常重要但也容易令人迷惑的概念之一。
简单来说,闭包是指一个函数能够访问并操作其外部函数的变量,即使外部函数已经执行完毕。
这是由于JavaScript的作用域链机制,函数在创建时会保存对其外部作用域的引用。
闭包的使用可以带来很多好处,但也容易导致内存泄漏和性能问题,因此需要谨慎使用。
2. 原型链(Prototype chain)原型链是JavaScript实现继承的一种机制。
每个对象都有一个原型对象,而原型对象又有自己的原型对象,形成一个链式结构。
当访问一个对象的属性或方法时,如果该对象自身没有定义,则会沿着原型链向上查找。
这种机制可以实现属性和方法的继承,但也容易导致混乱和不可预测的行为。
3. 异步编程(Asynchronous programming)JavaScript是一门单线程的语言,但通过异步编程可以实现非阻塞的操作,提高程序的性能和响应能力。
异步编程的方式有很多,包括回调函数、Promise、Generator和async/await等。
这些概念和技术需要理解其工作原理和使用方式,以便编写高效的异步代码。
4. 作用域(Scope)作用域是指变量和函数的可访问范围。
JavaScript采用的是词法作用域,即变量的作用域在代码编写时就确定了。
在函数内部可以访问函数外部的变量,但函数外部不能访问函数内部的变量。
此外,JavaScript还有全局作用域和块级作用域等概念,需要理解其作用和使用方式。
5. this关键字this关键字是一个非常复杂和容易引起困惑的概念。
它的值取决于函数的调用方式,而不是函数的定义位置。
在全局作用域中,this 指向全局对象(浏览器中是window对象),而在函数内部,this 的值可能会有所不同。
Javascript匿名函数与闭包(转)

Javascript匿名函数与闭包(转)请见如下⼀个闭包⽰例:color = "red";var obj = {color: "blue",getColor: function () {function displayColor() {return this.color;}return displayColor();}}console.log(obj.getColor());在getColor函数内部再定义了⼀个displayColor,再⼜定义了⼀个displayColor函数,从⽽形成闭包,最后将地上displayColor函数返回,这⾥发现这样定义其实作⽤不⼤,可以使⽤匿名函数替代直接返回:color = "red";var obj = {color:"blue",getColor: function () {return function() {return this.color;}}}console.log(obj.getColor()()); //输出 red闭包中匿名函数和this对象在javascript 中this 对象是基于函数的执⾏环境绑定的:在全局函数中, this等于全局环境即 window (浏览器环境)或者globle(node 中),⽽当函数作为某个对象的⽅法调⽤时this等于该对象。
不过匿名函数的执⾏环境具有全局性,其this 通常指向window(浏览器)或者globle(node环境),因此上⾯例⼦中,输出的是全局对象的 color定义。
为什么没有获得闭包外⾯定义的blue呢?如前⽂所述,函数被调⽤时,其活动对象会取得两个特殊的变量,arguments和this,因此在搜索的时候在作⽤域链的最前端即当前活动对象中就查找到了,不会进⼀步向上层查找。
不过我们可以把外部作⽤域的this对象保存在⼀个闭包能够访问到的变量⾥,这样就能够访问外层对象了:color = "red";var obj = {color:"blue",getColor: function () {var self=this;return function() {return self.color;}}}console.log(obj.getColor()()); //输出 blue最后,看⼀道百度2015年前端开发南京站笔试题:var myObject = {foo: "bar",func: function() {var self = this;console.log("outer func: this.foo = " + this.foo); //输出 barconsole.log("outer func: self.foo = " + self.foo); //输出 bar(function() {console.log("inner func: this.foo = " + this.foo); //输出 undefinedconsole.log("inner func: self.foo = " + self.foo); //输出 bar}());}};myObject.func();问,输出结果是什么?相信现在应该⽐较好理解了。
JS函数种类详解
JS函数种类详解JavaScript 中的函数是一种可重复使用的代码块。
函数可以用来执行特定的任务或计算特定的值。
在 JavaScript 中,函数分为以下几种类型:1.基本函数:这是最常见的函数类型,其包含了一系列的语句,用于执行特定的任务。
定义一个基本函数的语法如下:```function functionName(parameter1, parameter2, ...)//函数体//执行特定的任务//返回结果```其中,`functionName` 是函数的名称;`parameter1, parameter2` 是函数的参数;函数体是一系列的 JavaScript 语句。
2.匿名函数:匿名函数也是一种基本函数,但是没有名称。
它通常用作回调函数或作为其他函数的参数传递。
定义一个匿名函数的语法如下:```var functionName = function(parameter1, parameter2, ...)//函数体//执行特定的任务//返回结果```这里,`functionName` 是一个变量,通过变量名来调用这个匿名函数。
3. 箭头函数:箭头函数是 ES6 中引入的新语法,用于创建更简洁的函数。
箭头函数没有自己的 `this` 值,它会继承父级作用域中的`this` 值。
箭头函数的定义方式如下:```var functionName = (parameter1, parameter2, ...) =>//函数体//执行特定的任务//返回结果```这里的 `functionName` 是一个变量,通过变量名来调用这个箭头函数。
4. 构造函数:构造函数用于创建对象实例。
它是一个特殊的函数,以大写字母开头,通过 `new` 关键字调用。
构造函数的定义方式如下:```function ClassName(parameter1, parameter2, ...)//属性this.property1 = value1;this.property2 = value2;//方法this.method1 = functio//执行特定的任务//返回结果}this.method2 = functio//执行特定的任务//返回结果}```构造函数通常用于创建特定类型的对象,实例化一个对象时可以通过`new` 关键字调用构造函数。
JS中的匿名函数、回调函数、匿名回调函数
JS中的匿名函数、回调函数、匿名回调函数⼯欲善其事必先利其器在学习JavaScript设计模式⼀书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识。
九层之台,起于垒⼟。
在熟悉这⼀系列的概念之前,我们先来认识下JavaScript中函数吧。
⼀、定义函数的⽅式有两种:函数声明函数表达式函数声明格式如下: function functionName(arg0,arg1,arg2,...){ //函数体}function是关键字,然后functionName是函数的名字,这就是指定函数名的⽅式。
这个函数的name属性是functionName。
函数表达式最常见的⼀种格式如下:var varfun=function(){//函数体}创建⼀个函数并将它赋值给变量varFun,这种情况下创建的函数叫匿名函数(拉姆达函数)。
匿名函数的name属性是空字符串。
以下代码测试两种定义⽅式的name属性值:function fun(){}console.log();//funvar varfun=function(){}console.log();//空的⼆、函数调⽤⽅式匿名函数的⾃调⽤⽅式://⽆参(function(){})();//带参(function(a,b){alert(a+b);})(3,5);函数的回调⽅式:(通过函数指针调⽤函数)//firstfunction math(num1,num2){return minus(num1,num2);// return add(num1,num2);}function add(num1,num2){return num1 + num2;}function minus(num1,num2){return num1-num2;}alert(math(1,2));匿名回调函数:函数声明采⽤表达式形式,通过变量名调⽤。
深入理解Javascript闭包(closure)
最近在网上查阅了不少javascript闭包(closure)相关的资料,写的大多是非常的学术和专业。
对于初学者来说别说理解闭包了,就连文字叙述都很难看懂。
撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目。
一、什么是闭包?官方的解释是:所谓闭包,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。
我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。
看下面这段代码:function a(){var i=0;function b(){alert(++i);}return b;}var c = a();c();这段代码有两个特点:1、函数b嵌套在函数a内部;2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。
这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。
二、闭包有什么作用?简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
那么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。
因为a 执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。
javascript闭包是什么_javascript闭包有什么作用
javascript闭包是什么_javascript闭包有什么作用Java Script 闭包究竟是什么1.简单的例子首先从一个经典错误谈起,页面上有若干个div,我们想给它们绑定一个onclick方法,于是有了下面的代码《div id=“div Te st”》《span》0《/span》《span》1《/span》《span》2《/span》《span》3《/span》《/div》《div id=“divTest2”》《span》0《/span》《span》1《/span》《span》2《/span》《span》3《/span》《/div》$(document).re ad y(func ti on() {var spans = $(“#divTest span”);f or(var i = 0; i 《 spans.length; i++) {spans[i].onclick = function() {alert(i);}}});很简单的功能可是却偏偏出错了,每次alert出的值都是4,简单的修改就好使了var spans2 = $(“#divTest2 span”);$(document).ready(function() {for (var i = 0; i 《 spans2.length; i++) {(function(num) {spans2[i].onclick = function() {alert(num);}})(i);}});2.内部函数让我们从一些基础的知识谈起,首先了解一下内部函数。
内部函数就是定义在另一个函数中的函数。
例如:function oute rF n () {functioninnerFn () {}}innerFn就是一个被包在outerFn作用域中的内部函数。
这意味着,在outerFn内部调用innerFn是有效的,而在outerFn外部调用innerFn则是无效的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Javascript基础知识——匿名函数和闭包(2)
晚上休息过后,早上继续总结!
昨天晚上讲到了闭包,讲一下闭包里面的this对象!也是很有意思的!
在全局状态下,我们输出this的时候,一般是[object window]!
alert(this);
这个说明,在全局状态下,this代表的是window对象!
在某个对象内部呢,this代表的是这个对象!
var Box=function(name,age){
=name;
this.age=age;
}
那么在闭包里面的this,又代表什么呢?我们来看代码!
var user="The Window";
var obj={
user:"The Object",
getObjectUser:function(){
return function(){
return er;
}
}
}
分析这段代码!
第一行,在全局变量状态下建立了user,里面的值是”The Window”。
然后我们建立了一个Obj对象。
里面有user属性。
本来要返回user时很简单的,只要写run:function(){return er}即可!但是这里就有些奇怪了,我们写了一个闭包!分析闭包!函数名getObjectUser,函数的主体是return function(){……}。
当我们执行obj. getObjectUser(),后返回一个函数。
然后再执行!return er!本来我们以为会返回The Object!但是现在却返回了The Window!由此可见,闭包里面的this变量是当全局变量来用的!
也就是说,匿名函数里面的this.xxx变量时全局变量!那么我们如何变成局部的变量呢?用对象冒充比较方便:obj.getUser().call(obj)!还有一种方法在函数内部做!
var user="The Window";
var obj={
user:"The Object",
getUser:function(){
var that=this;
return function(){
return er;
}
}
}
教程中还讲到了内存泄露的问题。
个人感觉用处并不是很大,了解就可以了!接下来要讲到设计模式的问题了!
首先是javascript没有块级作用域这么一说!(if、for)我们如何来处理块级作用域?用类似下面的写法!
function box(count){
(function(){
for(var i=0;i<count;i++){
}
})()
alert(i);
}
这样写,里面的I就访问不到了!这种写法,教材里写道,一般都用在全局变量中!我们在全局中要做一些事情,把这些变量打包在匿名函数中,完成后自动销毁!挺好的!比如说
(function(){
var box=[1,2,3];
alert(box);
})()
然后讲到了一个构造函数的标准写法:
function Box(age){
var value=age;
this.getAge=function(){
return value;
}
this.setAge=function(age){
value=age;
}
}
这种写法比较好!体现了封装性!我感觉这种写法挺好的,但是教程中又说了,这样的写法也有不好的地方每次new Box()一下,里面的方法就会新开辟一个空间,不节约空间!于是有了新方法“静态私有变量”。
复杂的名字。
不知道怎么给那些高手想出来的!
(function(){
var user="";
Box=function(value){
user=value;
}
Box.prototype.getUser=function(){
return user;
}
})()
这段代码和刚才的构造函数还是有很大区别的!!我的个人理解:程序一运行后,在内存中开辟一块区域,里面有user这个静态变量!注意是静态变量!意思就是这个变量会被所有实例共享!Box是构造函数!注意没有VAR。
如果有了var 那么就变成局部变量了!然后给Box的原型赋值。
我们调用的时候var box1=new Box(“tmh”), var box2=new Box(“tmh2”)……始终是对静态变量user在修改!最后都直接访问user!画个图吧!
大概就是这么个意思!
(function(){
var user="";
Box=function(value){
user=value;
}
Box.prototype.getUser=function(){
return user;
}
Box.prototype.setUser=function(value){
user=value;
}
})()
这种写法就是所有的实例都可以去修改一个静态变量!这么写有什么用?不知道!我们再来看我们以前写过的对象:
var box={
name:"tmh",
age:34,
run:function(){
return name+" "+age;
}
}
用教材的话说,这些属性都是公有属性。
我们呢要把他们改成私有的!为什么又要这么写?天知道!
var box=function(){
var name="tmh";
var age=34;
function run(){
return name+" "+age;
}
var obj={
go:function(){
return run();
}
}
return obj;
}()
上面的是单例模式,还有更高级的。
但为什么要这么写,我真的不知道
function Desk(){};
var box=function(){
var name="xdh";
var age=34;
function run(){
return name+" "+age;
}
var desk=new Desk();
desk.go=function(){
return run();
}
return desk;
}()
alert(box.go());
最容易理解的方式就是把function(){}()里面的代码看成是在全局状态下!最后返回一个对象就可以了!。