回顾一下
一 基本类型和引用类型
1 五大基本类型:
String Number Boolean Null undefined //占有固定的内存大小,如数值型占八个字节,布尔类型占一个字节,他们的值 保存在栈空间,
2 三大引用类型
数组(array) 对象(Object) 函数(function)//引用类型占用空间内存不确定,但内存地址大小是固定的,存储的实际上是 数据的内存地址
3 在变量复制时候,基本类型复制的是值本身,而引用类型复制的是地址
二 执行环境和作用域
1 执行环境定义了变量或函数有权访问其他数据
2 全局执行环境是最外围的执行环境,在web浏览器中,全局执行环境是window对象,全局变量的声明关键词为var ,也可不写
3 内部环境可以访问到外部环境的变量和函数,但外部环境不能访问到内部环境的变量和函数
4 访问局部变量要比访问全局变量快
<script>
var name = "张三"; //定义全局变量
alert(name) //张三
alert(window.name); //全局变量,最外围,属于window属性
var a={
setName: function (){
return this.name;//undefinded this指向a
}
}
alert(a.setName());
</script>
<script>
var name = "张三"; //定义全局变量
alert(name)
alert(window.name); //全局变量,最外围,属于window属性
var a={
name:"李四",
setName: function (){
return name;// 张三 //直接访问全局变量name
}
}
alert(a.setName());
</script>
<script>
var name = "张三"; //定义全局变量
alert(name)
alert(window.name); //全局变量,最外围,属于window属性
var a={
name:"李四",
setName: function (){
return this .name;// 李四 this指向a
}
}
alert(a.setName());
</script>
下面再来体会几个作用域的例子
<script>
function setName(){
var name="张三"
function setYear(){ //setYear()方法的作用域在setName()内
var age=21;
var str=name+age+'岁了' ;
return str;
}
return setYear()
}
alert(setName()); //弹出 张三21岁了
</script>
<script>
function setName(){
var name="张三"
function setYear(){ //setYear()方法的作用域在setName()内
var str=name+age+'岁了' ;
var age=21;
return str;
}
return setYear()
}
alert(setName());//弹出 张三undefined岁了
</script>
//在函数执行过程中,首先是第一步是变量/函数提升,即为找出所有的变量和函数,将初始值设为undefined,然后根据程序运行顺序,在将本来赋予变量和函数的值赋值给它
三 内存管理
1. 内存分配:当我们申明变量、函数、对象的时候,系统会自动为他们分配内存
2 分配和回收都是自动完成的,当内存不在使用时就会被回收,如当函数执行完之后,则会立即被回收
<script>
// 为变量分配内存
var m= 123;
var n = "JavaScript";
// 为对象分配内存
var person = {
age: 25,
name: '张三'
};
// 为函数分配内存
function sum(m, n) {
return m+n;
}
alert(sum(m,n))
</script>
四 函数作为参数的几种方式
1.函数作为另一个函数的参数
2 有参函数函数作为参数
<script >
//第一种函数作为另一个函数的参数
function f(){
alert("我是作为参数的函数")
}
function s(a){//此处啊作为形参,可以是任意值
a();
}
s(f);
//第二种函数作为另一个函数的参数
function people(){
return 100
}
function sum(x,y){
alert(x+y())
}
sum(10,people)
//有参函数作为函数参数
function fun(a){
return a*a;
}
function ss(x,z){
alert(x+z(x))
}
ss(100,fun)
</script>
五 函数的内部属性
1 arguments 本质上相当于一个集合,表示函数参数的一个集合
2 使用arguments.length检测函数参数个数
<script > function sum(){ alert(arguments.length)//检测参数个数 result=0; for(var i=0;i<arguments.length;i++){ result+=arguments[i] } return result; }//求参数和 alert(sum(1,2)) alert(sum(1,2,3,4)); </script>
//内部属性具体举例
<script> //在函数外部使用this,this就指的是window对象 alert(this) //全局变量可以看做window对象的属性 var x=1; alert(window.x) alert(this.x) </script>
//函数内部调用
<script>
var x=1; function test(){ var x=0; alert(x) //这里的x为0 alert(this.x); //这里的x为1 alert(this) //window对象 } //test() //用new来调用,那么绑定的将是新创建的对象 function test2(){ this.x = 100; } var obj = new test2();//new改变this指向 alert(x); //这里的x为1 alert(obj.x);//这里的x为100 </script>
//作为某个对象的方法调用
<script type="text/javascript">
var x=1;
function test3(){
alert(this.x);
}
var objo={};
objo.x = 1000;
objo.s=test3;
objo.m = test3(); //相当于 window.test() this指向window
alert(x);//1
objo.m; //1
objo.s()//1000 //相当于window.objo.s() this指向objo //不懂可以看我第一篇文章
</script>
//事件监听函数中的this
<script>
var div1 = document.getElementById('div1'); div1.onclick = function(){ alert( this.innerHTML); //this指向的是div元素 }; </script>
一 匿名函数
定义:没有函数名字的函数
1.单独的匿名函数是无法运行和调用的
2. 可以把匿名函数赋值给变量
3. 通过(匿名函数)()来执行
4. 匿名函数传递参数(匿名函数)(参数)
接下来看一些小例子
<script >
<!-- //普通函数 -->
function people(){
alert("我是一个好人")
}
people()
// //把参数赋值给一个变量
var str=function(){
alert("把函数赋值给一个变量")
}
alert(str) //弹出函数体本身
str() //弹出结果
// 匿名函数
(function() {
alert("你是一个坏人")
})()
//带参数的匿名函数
(function(m,n) {
alert(m+n)
})(100,200)
</script>
这里提一下闭包,下节细讲
二 闭包
定义:闭包是指可以访问另一个函数作用域中的变量
在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁
常见方式
闭包的常见方式就是在一个函数中创建里另一个函数
作用:通过闭包可以访问局部变量
可以让局部变量始终保持在内存中
<script>
// 通过全局变量来累加
var num= 100;
function add() {
alert(++num);
}
add();
add();
add(); // 每执行函数一次,累加一次;
// 通过局部变量无法实现累加
function add(){
var num= 100; // 这里改为局部变量;
alert(num++);
};
add();add();add();
// 通过闭包实现局部变量的累加
function add(){
var num= 100; // 这里改为局部变量;
return function(){
num++;
alert(num);
}
};
// add()();add()();add()();//这种调用方式会出错,因为每次调用 num都会初始化一次;
var fn=add()//只在这里初始化一次,后边调用的时候执行的是里边的匿名函数
fn();fn();fn();
fn=null //应及时解除引用,否则会占用更多存
</script>