(三)Javascript从立即执行函数至包装类(含闭包问题)_javascript 立即执行函数改写为类-程序员宅基地

技术标签: JS学习笔记  javascript  

(三)Javascript从立即执行函数至包装类(含闭包)

立即执行函数
定义
- 此类函数没有声明,在一次执行过后即释放,适合做初始化工作。
//立即执行函数(只用一次,声明的话浪费空间)
//针对初始化功能的函数,形式如下:
(function abc(){
    
	var a = 123;
	var b = 234;
	cconsole.log(a+b)
}())
//在控制台中输入abc,会显示报错,abc is not undefined

//前后两个括号的作用,前面是形参,后面是实参
var num = (function(a,b,c){
    
    var d = a + b + c *2 - 2;
    return d;
}(1,2,3));

写法
//(function (){}());W3C建议第一种
//(function (){})();
//只有表达式才能被执行符号"()"执行,如何转为表示式?(+,-,=,括号里面转化成表达式)
function test(){
    
	......
}();
//这里语法上有错误,因为执行符号前面那一块不叫表达式,叫函数声明

var test = function(){
    
	console.log("a");
} ();
//这里可以执行,因为赋值号后面是函数表达式
//注意 : 能被执行符号执行的表达式,它的名字会被自动忽略
+ function test(){
    
	console.log("a");
}();
//这里被执行了,出现a。test的名字被忽略,显示EER:test is not defined


var test =(function(){
    
	console.log("a");
}());
//这里控制台会出现a,在控制台中输入test,它的值是undefined,他的类型是undefined

//一道阿里巴巴笔试题
function test(a,b,c,d){
    
	console.log(a + b + c +d);
}(1,2,3,4);

//这里因为(1,2,3,4);并没有被认为是执行符,所以被理解成下面:
function test(a,b,c,d){
    
	console.log(a + b + c +d);
}//这里被理解成了声明
(1,2,3,4);//这里是一个运算表达式(含逗号运算符),但其实没有意义


/*
在控制台输入test,得到 function test(a,b,c,d){
	console.log(a + b + c +d);
}
*/
    
闭包
定义

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。

作用
  • 实现公有变量

    • eg:函数累加器

    • function add(){
              
      	var count = 0;
      	function demo(){
              
      		count++;
      		console.log(count);
      	}
      	return demo;
      }
      var counter = add();
      counter();
      counter();
      counter();
      
  • 可以做缓存(存储结构)

    • eg:eater

    • function test(){
              
      	var num = 100;
      	function a(){
              
      		num++;
      		console.log(num);
      	}
      	functon b(){
              
      		num--;
      		console.log(num);
      	}
      	return [a,b];
      }
      var myArr = test();
      myArr[0]();
      myArr[1]();
      
      //得到结果:101 100
      
      
      
      function eater(){
              
          var food = "";
          var obj = {
              
              eat : function(){
              
                  console.log("i am eationg" + food);
                  food = ""; 
              },
              push : function(myFood){
              
                  food = myFood;
              }
          }
          return obj;
      }
      var eater1 = eater();
      eater1.push("banana");
      eater1.eat();
      
  • 可以实现封装,属性私有化(后期补充)

    • eg:Person();
  • 模式化开发,防止污染全局变量(后期补充)

一个闭包问题
//想要利用闭包依次打印出0~9
function test(){
    
	var arr = [];
	for(var i = 0; i < 10; i++){
    
		arr[i]=function (){
    
		document.write(i + " ");
		}
	}
	return arr;
}

var myArr = test();
for(var j = 0; j < 10;j++){
    
    myArr[j]();
}

/* 
这里打印出了10个10
首先这里是闭包,此道题的解题关键在于在函数体赋给arr[i]的时候,函数题里面的内容实际上是不被考虑的,当执行函数的时候,在arr[j]的作用域链中查找变量,即在作用域链第1位testAO中获取i,而i的值在循环的时候从0变到了10。

因此此处的关键就在于在将函数体赋给arr[i]的时候,是不考虑函数体内的内容的,所以也不会将i在循环中的值赋给函数体里面的document.write(i)。执行的时候才需要考虑,执行的时候才打开函数体内部。

所以myArr中的十个元素都是function(){
document.write(i + " ");
}
而不是function(){
document.write(固定的数 + " ");
}
*/
唯一解决方法(10对1AO转为1对1AO)
//利用立即执行函数
//①执行出数值再赋给arr,但这里显然脱离了闭包的思想
function test(){
    
	var arr = [];
	for(var i = 0; i < 10; i++){
    
		arr[i]=(function (){
    
		document.write(i + " ");
		})()
	}
	return arr;
}

var myArr = test();
for(var j = 0; j < 10;j++){
    
    myArr[j]();
}
//②从10对1个AO的关系变为1对1的关系
function test(){
    
	var arr = [];
	for(var i = 0; i < 10; i++){
    
		(function(j){
    
            arr[j] = function(){
    
                document.write(j + " ");
            }
        }(i));
	}
	return arr;
}

var myArr = test();
for(var j = 0; j < 10;j++){
    
    myArr[j]();
}

/*
这里重点关注第20~25行代码,解题关键:十个立即执行函数互不相同,影响它子函数被声明时所攥住的AO
第一次:i=0是实参传入立即执行函数中的j,这时是预编译四部曲的第三步,实参形参统一,j=0存入了AO中,之后赋给arr[0]的函数被声明(注意:声明的时候函数体内容被折叠,不考虑函数体中的内容)在赋给arr[0]的函数被声明的时候,这个函数攥住的AO,即作用域链第0位中含有j=0,之后立即执行函数结束。
到了第二次循环,又是一个新的立即执行函数,步骤与上面相同,但赋给arr[1]的函数的作用域链第0位中j=1(因为是一个新的立即执行函数,相当于开了一个新AO,所以说对应的房间不同)
*/
  • 可以实现封装,属性私有化。(需要联系到对象)

    • eg:Person();
  • 模块化开发,防止污染全局变量(后期)

对象
1. 属性的增删改查
var mrDeng = {
    
    name : "MrDeng",
    age : 40,
    sex : "male",
    health : 100,
    smoke : function(){
    
        console.log("I am smoking ! cool!!!");
        this.health--;
        //这里的this.health代表的就是medeng.health
    },
    drink : function(){
    
        console.log("I am drinking");
        this.health--;
    }
}

/* 属性的增加
	mrDeng.wife = "xiaoliu";
	在控制台中输入mrDeng,得到
	Obiect{	   
		age: 40,
		drink: ƒ (),
		health: 100,
		name: "MrDeng",
		sex: "male",
		smoke: ƒ (),
		wife: "xiaoliu"
	}
	
	属性的更改
	mrDeng.sex = "female"
	
	属性的删除
	delete mrDeng.name;
	
注意:访问不存在的属性,不会报错只会显示undefined
2. 对象的创建方式
/*
1.var obj = {} plainObject 对象字面体/对象直接量
2.构造函数(可批量生产对象,但相互独立,返回的值是对象)
	1) 系统自带的构造函数 new Object() Array() Number()
	2) 自定义构造函数 
*/
var obj = {
    
    obj.name = "abc",
	obj.sex = "male",
	obj.say = function(){
    
        
	}
}

var obj = new Object();
obj.name = "abc";
obj.sex = "male";
obj.say = function(){
    
    
}
//-----------------------------
function Car(){
    
    this.name = "BMW";
    this.height = "1400";
    this.lang = "4900";
    this.weight = 1000;
    this.health = 100;
    this.run = function(){
    
        this.health--;
    }
}
//这里是构造函数自定义写法,注意里面是等号和分号
//所以要用大驼峰式命明规则 TheFirstName 小驼峰:theFirstName
var car1 = new Car();
var car2 = new Car();
//car1 和 car2是独立的

//传递参数型构造函数
function Student(name,age,sex){
    
    this.name = name;
    this.age = age;
    this.sex = sex;
}
var s1 = new Student("zhangsan",18,"male");



//一个易错的地方
function Student(name,code){
    
    this.name = "zhangsan";
    this.code = "A001";
}
var s1 = new Student("lisi","A002");
console.log(s1.name+":"s1.code);
//这里得到的结果应该是"zhangsan":A001,而不是"lisi":"A002"
//因为函数里面并没有使用形参,this.name是属性不是参数
包装类
概念的引入
// 数字不一定都是原始值,原始值数字才属于原始值
//下面的也属于数字,但不是原始值
var num = new Number(123);
//这时候它属于对象123了
num.abc = "a";
console.log(num.abc);
//这里控制台得到"a"
console.log(num);
//这里控制台得到 Number{ abc:"a" , [[PrimitiveValue]]:123}
//值得注意的是,num虽然是对象123,但它仍然保持数字的特性
console.log(num*2);

//字符串类型对象
var str = new String("abcd");
//布尔型对象(先进行布尔运算,下面的意思是bol属性的初始值是true)
var bol = new Boolean(123);

注意:undefined和null没有属性,也就是说下面的情况会报错

console.log(null.abc);
console.log(undefined.abc);
包装类出现的过程
//首先从一个现象印出来
var str = "abcd";
str.abc = 'a';
//理论上原始值是不能赋予属性的,但这里并不报错
console(str.abc);
//控制台访问str.abc的结果是undefined

var num = 4;
//首先记住:原始值是坚决不可能有,但是为什么能调用呢?
//因为这里经历了一个叫做包装类的过程
num.len = 3;
/*隐式的发生下面的过程来弥补你的不足:
new Number(4).len=3
即先创建一个数字对象存原始数值,然后增加一个属性len=3; 但是执行完下一步就是销毁delete
*/
console.log(num.len);
//此处是访问num.len,所以又发生了 new Number(4).len,但是此处的len与上面不同,是undefined


//关于str.length
var str = "abcd";
str.length = 2;//发生包装类的过程
// new String("abcd").length = 2; delete
console.log(str);
// 这里得到的结果是"abcd"
console.log(str.length);
// 这里得到的结果是4,因为.length是字符串自带的属性
一道题
var str = "abc";
str += 1;
var test = typeof(str);
if(test.length == 6){
    
    test.sign = "typeof返回结果可能是String";
}
console.log(test.sign);
//这里得到的结果是undefined


练习
//百度一道题
var x = 1, y = z = 0;

function add(n){
    
	return n = n + 1;
}
y = add(x);
function add(n){
    
	return n = n + 3;
}
z = add(x);
//求x,y,z的值
//1,4,4

//该道题解题的关键是预编译四部曲和作用域
//首先应该是变量声明和函数声明提升
//第一个声明函数add被第二个声明的函数add覆盖,所以函数add的作用就只是返回n+3的值

//下面console.log是[1,2,3,4,5]的是
function foo(x){
    
    console.log(arguments)
    return x;
}
foo(1,2,3,4,5);
//这里是对的,因为arguments表示的是实参列表,尽管实参列表传入的只有一个,但实参列表属于外部

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_51458883/article/details/114949167

智能推荐

2024年,PHP前景的路在何方_php 2024-程序员宅基地

文章浏览阅读1k次,点赞9次,收藏8次。首先,我们需要了解PHP的优势和不足。然而,PHP也面临着一些挑战。随着技术的不断发展和市场需求的变化,PHP在某些领域中的竞争力可能会受到其他语言的挑战。PHP作为一种流行的Web开发语言,在过去的几年中已经证明了它的价值和实力。然而,未来的技术发展和市场需求是不断变化的,所以我们需要对PHP的前景进行深入分析,以便更好地应对未来的变革。总之,PHP的前景取决于它如何应对未来的技术和市场需求的变化。如果PHP能够保持其优势,不断适应新的挑战和机遇,那么它在未来的Web开发领域中仍然会发挥重要的作用。_php 2024

HTML基础-01_html圆形单选框-程序员宅基地

文章浏览阅读652次。一些琐碎的笔记。【>】可以指到下一级的标签 table>tr>td> table>tr3>td3无序列表: 有序列表: 自定列表: ul>li2 ol>li3 dl>dt{标题}>dd{内容}*3div标签纯盒子,margin有垂直塌陷被包含 div是独占一行的,span不能独占一行,span是可以接在后面的,块的大小就是内容的大小。 rowspan,合并行;colspan,合并列padding就是边框里面内容的距离。所以要加上高和_html圆形单选框

移动端 vue自定义指令 解决弹出键盘遮挡输入框_vue 全局解决手机输入法键盘弹出问题遮挡问题-程序员宅基地

文章浏览阅读2k次。XXX.JS 用于解决小键盘导致输入框被挡住的问题*/let startTop;let scrollDom;function adjustListener() { // 延时执行,等键盘弹出界面页面resize完成 setTimeout(() => { let { top: elTop, height: elHeight } = this.getBoundingClientRect(); let innerH = window.inne_vue 全局解决手机输入法键盘弹出问题遮挡问题

整数因子分解问题(递归+栈)-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏11次。整数因子分解问题及其扩展问题的解答_整数因子分解问题

Linux环境Nginx编译安装_linuxnginx编译安装-程序员宅基地

文章浏览阅读359次,点赞4次,收藏3次。Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的。Nginx 是一个很强大的高性能Web和反向代理服务,它具有很多非常优越的特性:在连接高并发的情况下,Nginx是Apache服务不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数的响应。_linuxnginx编译安装

spring框架下集成spring-session_spring 5.1.6集成spring session-程序员宅基地

文章浏览阅读750次。使用maven构建项目,pom.xml配置如下: org.springframework.data spring-data-r_spring 5.1.6集成spring session

随便推点

dns-程序员宅基地

文章浏览阅读123次。DNS域名解析服务一、DNS的原理:1.概述:DNS--域名解析系统;2.结构:三级、二级、顶级、.为根,全球一共十三个根DNS服务器;3.FQDN:完全合格域名,主机名(www)+域名后缀(baidu.com),用来描述全球唯一的一台主机;4.DNS解析记录:a.主机解析域名过程:找缓存--找hosts文件--netbios(仅限于windows主机)--DNS服务器--上一级DNS服务器b..._255dns

计算机软体专业,高考志愿填报:谈谈“计算机专业”这个“香饽饽”-程序员宅基地

文章浏览阅读101次。还有一周左右,今年高考的成绩就出来了。选择有时候比努力更重要,考生和家长们要提前准备好,对各个专业权衡利弊、横向对比,在填报志愿时才能做出最理性,最适合未来发展的选择。计算机专业,一直都是大热门专业,也是众多人的“真香”专业,今天就来分析一下,什么样的同学适合填报这个专业,它要怎么学,它的就业前景如何。一起来当“程序猿”和“程序媛”吧。一、什么样的同学适合学计算机?计算机专业不仅仅是理论学习,还有...

HRBUST - 1530-程序员宅基地

文章浏览阅读58次。题目My birthday is coming up and traditionally I’m serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each ...

joyful-pandas(下)学习笔记——第10章 综合练习_r语言端午节的淘宝粽子交易数据分析-程序员宅基地

文章浏览阅读281次。joyful-pandas(下)学习笔记——第10章 综合练习一、端午节的淘宝粽子交易首先读取数据data_Zongzi = pd.read_csv('Pandas(下)综合练习数据集/端午粽子数据.csv')#记得之前jupyter对中文路径支持不太好,现在居然也可以直接用了data_Zongzidata_Zongzi.columns#注意 ' 价格'和'发货地址 '列名中有空格#其实可以直接把列名中的空格strip一下的,好蠢Index([‘标题’, ’ 价格’, ‘付款人数’,_r语言端午节的淘宝粽子交易数据分析

新西兰计算机设计专业,2020年出国新西兰学习计算机专业的要求是什么?-程序员宅基地

文章浏览阅读97次。计算机课程优势非常之多,毕业生的就业机会也广,其中包括信息系统管理经理,信息技术顾问,多媒体开发管理员,网络管理经理,研发人员,网站管理员等等。综合来看,计算机专业是新西兰留学专业选择的一大热门推荐,包括院校推荐、发展前景、工作机会等等,学习计算机是理科和男生的第一选择。网络安全网络安全是国际合作课题。课题:企业网络信息安全管理、云计算机开发、专门课题:网络安全、研究方法和专题论文。健康信息学新开..._新西兰 计算机大专

如果不做软件测试了,我们还可以转行做这些……_不做测试,转行做什么-程序员宅基地

文章浏览阅读1.3k次。中国互联网的发展历史并不长,所以,我们看不到大多数40、50岁的测试人员在做什么?_不做测试,转行做什么

推荐文章

热门文章

相关标签