JS中闭包、函数与对象的介绍和用法

时间:2023-03-09 01:45:03
JS中闭包、函数与对象的介绍和用法

闭包

闭包概念:当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函,创建一个闭包环境,让返回的这个子程序抓住i,以便在后续执行时可以保持对这个i的引用。

内部函数比外部函数有更长的生命周期;函数可以访问它被创建时所处的上下文环境。

如:

页面中有10个div,循环绑定每个div的点击事件

var divs=document.getElementsByTagName("div");
for (var i=0;i<divs.length;i++) {
divs[i].onclick=function(){
alert(i);
}
}

运行结果:10

因为点击事件的函数内部使用外部的变量i一直在变化,当我们指定click事件时并没有保存i的副本,这样做也是为了提高性能,但达不到我们的目的,我们要让他执行的上下文保存i的副本,这种机制就是闭包。

修改代码:

var divs=document.getElementsByTagName("div");
for (var i=0;i<divs.length;i++) {
divs[i].onclick=(function(n){
return function(){
alert(n);
}
})(i);
}

n是外部函数的值,但是内部函数(点击事件)需要使用,返回函数前的n被临时驻留在内存中给点击事件使用,简单说就是函数的执行上下文被保存起来,i生成了多个副本。

对象

1、对象常量

对象的定义

//空对象
var obj1={}; //对象中的属性
var obj2={name:"foo",age:19};
var obj3={"nick name":"dog"}; //对象中的方法
var obj4={
price:99,
inc:function(){
this.price+=1;
}
}

对象中可包含的内容:

对象常量可以出现在任何允许表达式出现的地方,对象、数组、函数可以相互间嵌套,形式可以多种多样。对象的值可以是:数组,函数,对象,基本数据类型等。

 //对象中可包含的内容
var obj5 = [{
name: "jack"
}, {
name: "lucy", //常量
hobby:["读书","上网","代码"], //数组
friend:{name:"mark",height:198,friend:{}}, //对象
show:function(){ //函数
console.log("大家好,我是"+this.name);
}
}];
//对象中的this是动态的,指向的是:调用者
obj5[1].show();

2、对象取值

方法一:直接使用点号运算

            //3取值
var obj6={"nick name":"pig",realname:"Rose"};
console.log(obj6.realname);
//console.log(obj6.nick name); 错误

方法二:使用索引器,当对象中的key有空格是

            //3取值
var obj6={"nick name":"pig",realname:"Rose"}; console.log(obj6["realname"]);
console.log(obj6["nick name"]);

3、对象枚举(遍历)

var obj7={weight:"55Kg","nick name":"pig",realname:"Rose"};
for (var key in obj7) {
console.log(key+":"+obj7[key]);
}

4、对象更新与添加

如果对象中存在属性就修改对应值,如果不存在就添加。对象通过引用传递,它们永远不会被复制

var obj8={realname:"King"};
obj8.realname="Queen"; //修改
obj8.weight=1000; //添加属性
obj8.show=function() //添加方法
{
console.log(this.realname+","+this.weight);
}
obj8.show();
输出:Queen,1000

5、对象封装

使用对象封装的好处是可以减少全局变量的污染机会,将属性,函数都隶属一个对象。

封装前:

var name="foo";   //name是全局的,被暴露
i=1; //全局的,没有var关键字声明的变量是全局的,与位置关系不大
function show(){ //show 是全局的,被暴露
console.log("name->"+name);
console.log(++i);
} //i是全局的 2
show();
//3
show();

封装后:

	//对外只暴露bar,使用闭包封装
var bar=function(){
var i=1;
return{
name:"bar",
show:function(){
console.log("name->"+this.name);
console.log(++i);
}
};
}; var bar1=bar();
//2
bar1.show();
//3
bar1.show(); var bar2=bar();
//2,因为被封装,且闭包,i是局部私有的
bar2.show();

函数

1、参数对象 (arguments)

第一个函数中有一个默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数

function counter(){
var sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
} console.log(counter(199,991,1,2,3,4,5));
console.log(counter()); 运行结果:
1205
0

这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容

2、构造函数

在javascript中对象构造函数可以创建一个对象。

 /*构造函数*/
//可以简单的认为是一个类型的定义
function Student(name,age){
this.name=name;
this.age=age;
this.show=function(){
console.log(this.name+","+this.age);
}
} //通过new关键字调用构造函数,创建一个对象tom
var rose=new Student("rose",18);
var jack=new Student("jack",20); rose.show();
jack.show(); 结果:
rose,18
jack,20