1.Js的特点(PHP也是)
1.弱类型语言
2.直译型语言(不需要编译)
3.不是完全的面向对象(cs5以前)
4.跨平台
5.具有动态性,基于事件驱动形式
2 Js引入方式
1.内部引入
<script ></script>
2.外部引入 <script src=" "></script>(标签内部不能写js代码,无效)
3.行间引入
<a href="javascript:alert('陈圆圆');">陈圆圆</a>
<button onclick="alert('测试');">haha</button>
3.命名方法
1.小驼峰命名法
第一个字母的首字母小写,以后每一个单词的首字母大写 bigBirdAbc
2.大驼峰命名法/帕斯卡命名法
每个单词的首字母大写BigBirdAbc
3.匈牙利命名法
属性(s_:静态,g_:全局)+类型(object,i:int,a:array)
+描述(对象的名字) g_obj_bird
4.变量的命名规范
1.见知明意
2.变量名只能是数字,字母,下划线,$组成,并且不能以数字开头
3.不能使用系统的关键字(var)和保留字(class)作为变量名
5. 常量声明
常量一旦声明,永不改变conset
console.log(Math.PI);
变量:声明以后它的值是可以修改的
声明变量的关键字是var
01声明变量必须添加关键字 var
02不写var bird = 'gaga'; 变量默认为全局变量,基本不要这样用
03如果一个变量,被声明多次,定义多次,也不会报错,
后定义的会覆盖先 定义的值
6.数据类型
基本
1.number整数和小数
2.string 字符串;类型
3.boolean 类型 true false
4.undefined类型
5.null 类型
引用
6.array[]
7.function(){}
8.object 对象类型
7. 检测数据类型 typeof( )
typeof(变量) 用来检测变量属于哪一个类型
特殊的number NaN
特殊性在于 他是唯一一个自身与自身比较,返回值为false的元素
格式占位符输出
格式的占位符有:%d(数字)%i (整数) %o(对象) %f(小数)
例:console.log('今年是%d年', 2021);
8.字符串
字符串可以用单引号也可以用双引号包裹
单引号的字符串,内部只能使用双引号
双引号的字符串,内部只能使用单引号
** 反引号 字符串两端反引号,内部变量或者运算用 ${ }
`the result is ${1 + 2} lalala`
9.字符串的转义字符
\n 换行
\t tab键
\' 单引号
\" 双引号
\\ 表示 \
10.运算符
1.算术运算符
2.关系(比较)运算符
3.逻辑运算符
4.三目运算符 a?b:c 当a为真,则执行b,当a不为真,则执行c
5.赋值运算符
1-5的优先级由强到弱
常用:()> ! >算数 > 比较> || > && > 赋值
算数运算符
+ - *(乘) /(除) %(取余)
+ ++(自增) --(自减)
+= -= *= /= 自身+1 -1 ...
## 01转换为number类型
var str3 = '李煜';
** var str4 = +str3;
console.log(str4, typeof str4);
str4 为NaN,类型为number
(正号,隐式转换为number类型)
console.log(str4, typeof str4);
## 02字符串+数字 不管顺序只要有字符串都会转换为字符串
## 03除+以外的所有运算符都可以把string转换为number类型
var str5 = '123';
var str6 = '321';
var num5 = str6 - str5;
console.log(num5, typeof num5);
** var num6 = str6 - 0; // 比较常用
console.log(num6, typeof num6);
console.log(str5 * str6);
console.log(str5 / str6);
## 04.% 模运算 ,取余
console.log(10 % 3);
05. ++ 自增
-- 自减
c = a++ 相当于先把原来的a赋值给c,再完成a的自增
c = ++a 相当于先完成a的自增,再把a自增后的值赋给c
var num1 = 10;
var num2 = num1++;
console.log('num2',num2); // num2=10 num1=11
console.log('num1',num1); // num1=11
var num3 = ++num1; // num1=12 num3=12
console.log('num3',num3);
++num1;
num1++; // num1 = num1+1
console.log('num1',num1); //num1=14
console.log('num1',num1++); //先输出内容,再++
console.log('num1',++num1); // num1=16
// 练习
var k=10;
var j = (k++)+3; // k++运算的优先级最低 ,先算k+3,此刻的k=10,
然后再赋值给j,最后计算k++,本行代码的执行结果是 j=13 k=11
console.log(j,k);
var m = 10;
var n = ++m + m++ + m;//n=34
1.++m m的值变成11,并且让11参与运算
2.m++ 先取出m的值11,让11参与运算,然后再自增,变成12,随后参与运算
11.逻辑运算符
或 || : 有一个为真即为真(真即为 true)
与(且) && : 同真为真(所有表达式必须都为真的时候,结果才是true)
非 ! : 取反 (非真 !true 为 false)
逻辑表达式的返回值,可以为true和false,也可以是具体的数值
非0即为真
5>7||console.log('古来征战几人回')
||5||console.log('古来征战没人回');
逻辑运算符的短路写法
表达式1||表达式2||表达式3....||表达式n 从左至右遇到第一个表示的结果
为true的时候,后面的表达式均不执行
表达式1&&表达式2&&表达式3....&&表达式n 从左至右遇到第一个表示的
结果为false的时候,后面的表达式均不执行
var num1 = 10;
var num2 = 5>3&&num1++;
console.log(num2,num1);
/*
1. !优先级很高,比算术运算符都高
**2. boolean和number都参与运算的时候,会把boolean转化为number,
他是一个隐式转化,其中true转为1,false转化为0
12.赋值运算符
= += -= *= /=
a+=1 => a=a+1
字符串拼接
var str = '饕餮';
str += '赑屃';
var num3 = 10;
num3+=1; // num3 = num3 + 1;
console.log(num3);
13.显式转换
1.转为string String(内容)
2.转为number Number(内容)
3.转为boolean Boolean(内容) ,
0,‘ ’,null NaN,undefined 返回false,其他为true
空字符串是 '',空格也算字符 ' ' 不是空字符串
14.获取元素对象名
1.document.getElementById(元素id)
2.document.getElementsByTagName('元素的标签名')
3.document.getElementsByClassName('元素的类名')(ie8以下不支持)
注:标签.用以查找标签内部的元素或者类或者id
15.弹出框
1.提示框,输入框
window.prompt("sometext","defaultText");(提示框,输入框)
console.log(pto);(返回值是输入值或者null(取消))
2. 确认框
var r = confirm("请按按钮");(返回true 或者false)
3.警告框
alert()
注:都是window方法可以不写window
16.分支语句if(分支结构),for(循环结构)
if 语句
if(){}
if(){}else{}
if(){}elseif(){}...else{}
注:a.可内部嵌套if; b.语句本身不能使用return ,break;
switch-case语句
var count = '黑猫警长';
switch (count) {
case '大头儿子':
console.log('大头儿子');
break;
case '奥特曼':
console.log('奥特曼');
break;
default:
console.log('没有童年');
break;
}
循环语句
1.for(循环变量的初始值;循环条件;循环变量的增值){
循环体
}
for循环执行流程
1.查看循环变量的初始值,是否满足设置的循环条件
2.如果满足设置的条件,执行循环体内的代码
3.执行完毕之后,执行循环变量的增值操作
4.在下一次循环中,依次执行 1->2->3
5.直到循环条件不满足的时候,结束当前循环
2.while
while(循环条件){ 循环体 }
只有当循环条件满足的时候,才能进入循环体,当循环条件不满足的时候,
循环结束
3.do-while
do{ 循环体
}while(循环条件);
它和while唯一的区别是,while是先判断条件是否满足,然后再执行
循环体中的代码
do-while是先执行循环体,然后再判断条件是否满足,如果满足,
再执行循环体
注:
a.continue 和 break ,都是用来终止循环的,可以应用在任何循环体
上,包括 for,while,do-while
b.continue 终止本次循环,继续下一次循环
c. break 终止本层循环,整个循环被终结(循环嵌套中)
break 在for循环中使用的时候,终止的是本层的循环,不是所有的循环
17.window.onload
window的load事件,是在文档加载完毕以后,并且文档中所有资源都加载
完毕以后,才执行load方法中的代码(文档资源包括,图片,音频,视频等)
如果不使用window.onload,直接访问某个元素,此刻该元素还没有加载到
dom结构中,那么访问该元素返回一个null,因此如果把代码写在head中,
必须window.onload绑定,然后执行代码
window.onload=function(){}
18.HTML里边插入内容
01.document.write('')
向文档流写入内容
特点:
1.可以写入文本内容,也可以写入标签
2.后面的内容,不会覆盖前面的内容
3.写入到body中
02. ele.innerHTML='';
向元素中写入内容
1.可以写入文本内容,也可以写入标签
2.后面的内容,会覆盖前面的内容
03.innerText=
1.写入的是文本
2.会覆盖元素中的所有内容
19.随机数
Math.floor() 向下取整
Math.round() 四舍五入
Math.ceil() 向上取整
Math.random() 取值范围是 [0,1),0到1,取到0,但是取不到1
// 获取[m,n] 区间的随机整数
// Math.floor(Math.random()*(n-m+1)+m)
20.this
函数的时候指的window
对象方法的时候指的这个对象
ex-01
var lis = document.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
lis[i].abc = i;
lis[i].onclick = function () {
alert(this.abc + 1);
};
}
for(var i=0;i<10;i++){
(function(k){
lis[k].onclick = function(){
alert(k+1);
};
})(i);
}
21数组方法
a. 清空数组,arry.lengh=0;
b. 数组中,可以放变量,可以放表达式,可以放不同类型的数据
*数组方法
原来数组上修改 push,pop,unshift,shift,splice ,toString
新的数组 some,every,filter,map concat,split,join,reverse
sort ,indexof
1.数组的增删
arr.push(a,b,c)
向数组的尾部加入元素
参数:可以是多个
返回值是 新数组的长度
2.arr.pop()
从数组的尾部删除一个元素,每一次删除一个元素
没有参数,返回值是删除的那个元素
3.arr.unshift(a,b,c)
向数组的头部加入元素
参数:可以是多个
返回值是 新数组的长度
bug: IE6/7 下没有返回值
4. arr.shift()
从数组的头部删除一个元素,每一次删除一个元素
没有参数,返回值是删除的那个元素
5.splice()
从数组的任何一个位置开始,进行删除,替换,添加任意元素
参数:(以下序号代表参数的次序)
a.指定开始操作的位置
b.指定删除元素的长度,包括开始的位置
c.从开始的位置,添加的新元素
ex: var arr3 = arr2.splice(2,1,'努尔哈赤','冯保');
返回值
当删除了元素的时候,返回的删除的元素组成的数组,如果没有删除,
则返回空数组
注:
当只有一个参数的时候,从该参数指定的位置,包含该参数位置上的元素,
一直到最后,全部删除
当有两个参数的时候,表示,从第一个参数的位置开始删除,删除长度为
第二个参数值的所有内容
新的数组
6.slice()截取子数组
参数
1.开始位置
2.结束位置
特点:
1.包含开始位置,不包含结束位置
2.参数为负数的时候,倒数第几位,从1开始计算
3.参数只为能为整数,所有的非法字符都会被解析为0
4.如果参数为1个,则截取到的子数组就是从该参数开始,一直到最后,
也就是 结束位置默认到最后
5.如果没有参数,则是整个数组的复制操作
6.开始位置必须在结束位置之前,否则截取不到任何数组
7.arr.every() 监测数组中的元素是否都满足设置的条件,如果满足则
返回 true,否则返回false
arr.some() 监测数组中的元素是否有满足设置的条件,如果满足则返回
true,否则返回false
参数 3个
a.条件函数
条件函数的参数有3个
1.数组中的元素
2.数组中该元素对应的下标
3.当前操作的数组
b.数组的索引(下标)(可选)
c.指定函数中的this指向 (可选)
ex
var arr1 = [5,6,7,8,9,10];
var bol1 = arr1.every(function(item){
// 在函数中,添加设置的条件,item指的是数组中的每一个元素
return item>4;
});
console.log(bol1)
8.arr .filter(function(){})
数组元素过滤(筛选)(三个参数,和some一样)
var arr2 = [1,2,3,4,5,6,7,8,9,10];
var arr3 = arr2.filter(function(ele){
return ele%2==0;(不是赋值,是结果=所以为==)
});
console.log(arr2,arr3);
9. arr.map(function(){})
数组的映射,工作中常用于循环
(给数组中的每一项进行相同的添加,修改)
var arr4 = arr2.map(function(ele){
return ele+'px';
});
console.log(arr2,arr4);
10.arr.concat(arr1,arr2,arr3)
把多个数组合并成一个数组
返回值是一个数组
11.把字符串切割成一个数组
str.split()
调用对象是一个字符串,返回值是数组
参数是一个切割符,切割符必须是字符串当中存在的字符,或者是' ' ;
12.把数组中的元素合并成一个字符串
arr. join()
参数只有一个,表示连接符,如果不设置,连接符默认是逗号
返回值是一个字符串
12. 数组倒序
arr.reverse()
该方法没有返回值,改变数组本身
13.数组排序
arr.sort(function(a,b){return a-b}) 该函数修改是原数组
a.默认排序,先把number转化为字符串类型,然后依次比较每一个字符串
的大小
b.return num1-num2:从小到大排序
c.return num2-num1:从大到小排序
d.return 0或者正数:原排序不变
e.return 负数:原排序倒序
arr11.sort(function(num1,num2){
return num2-num1;
});
console.log(arr11);
14.数组提取
arr.indexOf(a,n)获取指定元素的下标
参数有两个
1.指定查找的元素
2.指定开始查找的位置
特点
1.从指定开始查找,如果不写第二个参数,默认从0开始查找
2.返回元素所在的下标位置
3.如果找不到,则返回 -1,表示数组中没有要查找的元素
4.第二个参数不能为负数
5.低版本IE(6/7/8)不支持
ex. console.log(arr5.indexOf('李成梁',2));
22.遍历数组(3种方法)
1.for()
2.for in 不仅可以遍历数组,还可以遍历对象
3.arr.forEach(function(item){console.log(item)
) ,低版本ie(6,7)不支持
var arr10 = [4,3,5,6,78,90];
for(var i=0;i<arr10.length;i++){
console.log(arr10[i]+10);
}
for (var ab in arr10) {
console.log(ab,arr10[ab]);
}
var obj = {
name:'西门庆',
age:20,
job:'暴发户'
};
console.log(obj);
for (var ab in obj) {
console.log(ab,obj[ab]);
}
arr10.forEach(function(item){
console.log(item);
});
23 数组打乱
a.sort() 函数中如果返回值<0,则交换两个元素的位置,如果返回值>=0,
不交换位置
var arr12 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr12.sort(function () {
return Math.random() - 0.5;
});
console.log(arr12);
24冒泡排序
var arr1 = [23,45,1,23,45,56,7,6,8,0,34,65];
for(var i=1;i<arr1.length;i++){ // 外层控制趟数
for(var j=0;j<arr1.length-i;j++){
if(arr1[j]>arr1[j+1]){
//交换位置
var temp = arr1[j];
arr1[j] = arr1[j+1];
arr1[j+1] = temp;
}
}
}
console.log(arr1);
25.二维数组
var er1 = [[1,4,7],[0,4,8],[34,89,190]];
var min = er1[i][j]; //获取第一个数组中的第一个元素,
26.Math常用方法
Math.floor() 向下取整
Math.round() 四舍五入
Math.ceil() 向上取整
Math.random() 随机数
Math.pow() 幂函数
参数俩个
1.底数
2.指数
Math.sqrt() 开平方运算,参数不能为负数,如果为负数,取值为 NaN
Math.abs() 绝对值
Math.min() 最小值
Math.max() 最大值
最大值和最小值的参数可以有很多个,但是不能是数组,如果要查找数组
中的最大和最小,需要借助于apply函数,apply可以 向max传递一个数组
求数组中的最大最小值
Math.min.apply(null,arr);
Math.max.apply(null,arr);
27.字符串方法
charAt,charCodeAt,String.charCode(字符编码)
subString(),slice(),subStr()
toLowerCase,toUpperCase
indexOf,lastIndexOf
concat,trim,split
1.charAt() 获取指定位置上的字符
参数1,指定字符的位置,如果不写,就从第一个字符开始获取
(不支持负数)
返回值是查找到的字符
2.charCodeAt() 获取指定位置上的字符的字符编码
特点同 charAt()
常用字符编码
0-9:48-57
a-z:97-122
A-Z:65-90
3. String.fromCharCode(字符编码) 把提供的字符编码,转换为对应的
字符,调用对象不再是字符串,而是String,他是String的一个静态方法
var str1 = '你是人间的四月天';
字符串转成编码
var code1 = str1.charCodeAt(2);
//编码转换成字符串
var str3 = String.fromCharCode(code1);
截取字符串
4.substring() 截取字符串中的子字符串,两个参数
a.第一个参数 指定截取开始的位置
b.第二个参数 指定截取的结束位置
特点:
1.参数只能是正数和0,非法的参数都会被解析为0
2.如果没有参数,则从头截取到尾部
3.如果只有一个参数,则从参数指定的位置,截取到尾部
4.如果有两个参数,参数会比较大小,小的为开始位置,
大的为结束位置
5.包含开始位置,不包含结尾位置
5.substr()
参数是两个
1.开始截取的位置
2.截取的长度
特点:
1.第一个参数可以是0 正负整数
2.在低版本ie(6/7/8)下,第一个参数不能为负数
6.str.slice() 字符串截取
参数为两个
1.开始位置
2.结束位置
特点:
1.参数的值只能为整数(正负整数和0),非法字符会解析为0
2.不会比较大小,当两个调换的时候,会截取不同的内容
3.参数都省略的时候,相当于复制
4.只有一个参数的时候,从参数位置截取,一直到最后
5.值为负的时候,倒着数,从1开始
字符串下标
获取一个小字符在这个字符串中的下标位置
7.str.indexOf(a)
8.str.lastIndexOf(a)
和数组的使用方式一样
参数
1.要查找的字符串
2.开始查找的位置
如果找不到,返回-1
9.字符串转化
str.toLowerCase() 大写转小写
str.toUpperCase() 小写转大写
10.去除字符串两边的空格
str.trim()
没有参数,新增方法,低版本ie不支持
低版本也可以用正则表达式
x.replace(/^\s+|\s+$/gm,'')
11.split() 把字符串切割成数组
参数是切割符号
ex:
var str22 = '朱温&李克用&石敬瑭&刘知远&郭威';
var arr = str22.split('&');
12.字符串拼接, 和 + 拼接是一样的
str.concat()
28.计时器
2.1 间隔计时器
每间隔多长时间,执行一次某个操作
计时器的返回值,返回值是一个number,是浏览器给计时器的
一个编号,谷歌是从1开始的,火狐是从2开始的,IE也是一个
编号,无论任何浏览器,从第一个计时器开始,编号会越来越大.
**为了防止用户多次连续点击重启,导致计时器累加,需要在重启之前先
清除计时器
//启动定时器三种方法
// 第一种方式:执行函数是一个匿名函数
var num = 0;
var abc = setInterval(function(){
num++;
console.log('同一个世界同一个梦想'+num);
},1000);
console.log(abc);
//第二种方式:执行函数是一个 普通函数
var wp = document.getElementsByClassName('wp')[0];
var num1 = 0;
// 声明一个函数
function ab(){
num1++;
wp.innerHTML = num1;
}
// setInterval(ab,500);
//第三种方式 执行函数是一个字符串
// setInterval('ab()',500);
2.2 延迟计时器
推迟多长时间,执行一次某个操作
setTimeout(function(){
},2000);
清空计时器
参数num指向一个计时器
clearInterval(num); //清空间隔计时器
clearTimeout(num); //清空延迟计时器
清空所有计时器
var aa = document.getElementById("aa");
aa.onclick = function(){
for(var i=0;i<100;i++){
clearInterval(i);
}
};
29.自定义函数
具名函数:具有名字的函数
匿名函数:没有名字的函数
立即执行的匿名函数(function(){})()
特点
*return想返回多个数据的时候,需要借助数组和对象来实现
*没有返回值的函数,实际上返回了 undefined
function show2(){
var str = '百里守约';
var arr = ['韩信','刘邦'];
var bol = false;
return [str,arr,bol];
}
30.全局变量和局部变量
a.在js全局范围中,不能访问函数内部声明的变量或者函数,然而在一个
函数中,访问外面声明的变量和函数,简言之就是外面看不见里面,
里面看得见外面
b.如果两个函数同名,则第二个函数会把第一个函数覆盖
c.当在函数的内部声明变量的时候,如果不加var关键字,此时变量就相
当于是一个全局变量,前提是没有重名的局部变量,如果加上var关键字,
就是一个局部变量
d.所有的全局变量和全局函数,都是声明在window上,可以理解为都是
window对象的属性
e.就近原则,在函数内部优先选择当前作用域的变量,如果当前作用域中
没有该变量,就往该函数的外部一层作用域中查找变量,这杨依次寻找
下去,直到找到全局作用域的位置,如果还没有该变量,就报错,
如果有就输出.
f.当存在多个script 标签的时候,会按照浏览器解析顺序进行执行,先
解析的script 标签中的全局变量和函数,能在后解析的script 标签中
使用,但是后解析的script 标签中的全局变量和函数,不能在先解析的
script 标签中使用.
31.对象
获取对象的属性
1. obj.属性名
2. obj['属性名']
console.log(obj1.name); //获取对象obj1的name属性的value值
console.log(obj1['name']);
obj1.ab(); //调用对象的方法
给对象添加属性和方法
1. obj.属性名='属性值'
2. obj['属性名']='属性值'
遍历对象
for(var key in obj3){
console.log(obj3[key]);
//console.log(obj3.key);
}
32.对象和字符串相互转换(Jason)
对象转字符串 str=JSON.stringify(obj)
字符串转对象 obj=JSON.parse(json类型的字符串);
json和对象大致一样,只是json的key和value都必须使用双引号括起来
json数据中一般没有方法
33.创建对象4种方式
对象:特指某个事物,具有属性和方法
创建对象:实例化一个对象的同时对其属性进行初始化
01字面量创建对象
var obj1={
name:"amethyst",
color:"blueviolet",
code(){
console.log('love coding');
}
}
console.log(obj1.color);//blueviolet
obj1.code();//love coding
02.调用系统的构造函数创建对象
var obj2=new Object();
obj2.name="lanlan";
obj2.color="pink";
obj2.eat=function(){
console.log('love eating');
}
console.log(obj2.name);//lanlan
obj2.eat();//love eating
03.工厂模式创建对象
function creatObject(name,hobby){
var obj=new Object();
obj.name=name;
obj.hobby=hobby;
obj.sleep=function(){
console.log('sleep all day');
};
return obj;
}
var obj4=creatObject('zhao','eating');
console.log(obj4.name);//zhao
obj4.sleep();//sleep all day
04.自定义构造函数创建对象
function Person(name,age){
this.name=name;
this.age=age;
this.dream=function(){
console.log('go ahead');
}
}
var obj3=new Person('puppy',18);
console.log(obj3.name);//puppy
obj3.dream();//go ahead
*在js中,构造函数可以看成是一个类
*当使用new调用构造函数的时候,构造函数内部会自动创建一个空对象({}),
并且使构造函数内部的this指向这个对象,然后再构造函数的最后,自动返回这个对象
*new 操作符作用
1.构造函数内部会自动创建一个空对象
2.改变this指向,把this指向当前对象
3.在构造函数的最后返回该对象
工厂模式创建对象和自定义构造函数创建对象都是函数,都可以传入参数,不同的是:
工厂模式函数名是小写,有new,new之后的对象是当前对象,有返回值,直接调用函数就可以创建对象;
自定义构造函数的函数名首字母大写,没有new,没有返回值,this是当前对象,通过new的方式来创建对象
33.Date 日期对象
声明一个日期对象 var date = new Date();
Date 中常用的函数,返回值都是number
getFullYear(): 获取的是当前年份
getMonth():获取当前日期对象中的月份,从0开始计算
getDate(): 获取当前月份的第几天
getDay(): 获取星期几,0-6 0代表周日
getHours(): 获取当前日期对象中的小时数,0-23
getMinutes(): 获取当前日期对象中的分钟数,0-59
getSeconds(): 获取当前日期对象中的秒数,0-59
getMilliseconds() 获取毫秒
getTime() : 时间戳,返回的是1970年1月1日早上8点到当前时间的
毫秒数
创建固定日期的date对象,必须在Date中写入日期参数
1.Date(年,月,日,时,分,秒) 注意:月份-1
2.Date("月 日 年 时:分:秒")
3.Date("月 日,年 时:分:秒")
var date2 = new Date(2021,2,27,12,0,0);
var date3 = new Date("3 27 2021 12:00:00");
var date4 = new Date("3 27,2021 12:00:00");
34.数据类型
字符串,数字,布尔,对象,undefined
ECMAScript 变量有两种数据类型:基本类型 和 引用类型,也有其他
叫法,比如说 原始类型和对象类型,拥有方法的类型和不能拥有方法
的类型,还以可以分为可变类型和不可变类型,其实这些叫法都是
根据这两种类型的特点来命名的
基本类型的特点
1.基本类型的值不可变
2.基本类型的比较是值的比较
3.基本类型的变量存在于栈区中(栈内存,数据 先进后出)
栈存放数据,先进后出,自动分配内存空间,自动释放
堆,先进后出,动态分配内存,大小不定,也不自动释放
function foo() {
var a = 1;
bar();
}
function bar() {
var b = 2;
hello();
}
function hello() {
var c = 3;
}
foo();
//先进后出不是赋值算进,使用算出;而是赋值算进,被清理算出。而且在同一函数作用域下
的变量,应该位于栈的同一层。
//这里的声明顺序显然是 1 2 3,释放顺序显然是 3 2 1。
引用类型的特点
1.引用类型的值可变
2.引用类型的值同时存在于栈内存和堆内存中
3.引用类型的比较是引用的比较
js中的引用类型 数组和对象
35.arguments
在每一个函数中,都有一个arguments类数组,在他里面存储着这个函数的
所有参数,他是一个数组的形式,但是不是数组,不能执行数组的删除和
添加方法,只能进行读取
// arguments.callee 指的是当前所在的函数本身
36.闭包
是指有权访问函数另一个作用域中的变量的函数
(函数嵌套函数,内层函数访问外层函数的变量或者返回值)
在需要使用的外层变量定义的时候闭包就已经产生
特点
延长局部变量的生存周期
外部可以读取内部函数变量
作用
(可以用于框架和插件的封装)
缺点
由于闭包会携带包含它的函数的作用域,因此他会比其他的函数占用
更多的内存,过度使用闭包可能会导致内存占用过多,造成页面假死。
建议只在绝对必要的时候考虑使用闭包,能不用,就不用!