作用域的赋值规则
1、局部作用域的查找规则
var a=20;
function fn1(){
function fn2(){
function fn3(){
console.log(a);
}
fn3();
}
fn2();//函数fn1执行同时执行fn2
}
fn1();//执行函数fn1
//逐层向上层查找,注意一定是向上查找!!一直到找到为止,找不到就报错。
2、局部作用域的赋值规则
function fn1(){
function fn2(){
function fn3(){
a = 40; //这里不声明,直接赋值
console.log(a); //可以打印 40
}
fn3();//调用之后,a会声明并提升至上层,如果上层也没有声明a,则会一直向上声明且赋值a=10;即该函数调用后会执行a的值。
console.log(a); //也会执行 40
}
fn2();
}
fn1();
console.log(a); //也会执行 40
总结:局部作用域的赋值规则,会先赋值给本作用域声明的变量,如果本作用域没有声明该变量,那么这个赋值就会赋值给外层作用域 ,外层作用域如果也没有声明该变量,那么会逐层向外层赋值;如果外层作用域都没有声明改变量 ,那么该变量就会赋值给全局区域。
function fn(){
a = 10; //如果没有声明 a变量 ,那么调用函数的时候 a变量的赋值会向上赋值,不要这样写,很不规范,语法不严谨。正常的都要var,但是大家了解这个不声明会逐层向上赋值的情况。
}
fn(); //函数调用了,那么赋值就会赋值给外层作用域
console.log(a);//执行 10
注意 : 不管是在函数内部,还是在函数外部 ,不声明变量的写法,都很少用;但是大家要知道,函数里赋值变量,不声明的话,那么变量的赋值会逐层向外赋值。
自执行函数
最大的作用:主要是为了区分作用域,这样相互之间就不会受到影响;
(function(){
var a=10;
function fn(){
console.log("fn111")
}
fn();
console.log(a);
})();//执行 fn111
10
(function(){
var a=10;
function fn(){
console.log("fn111")
}
console.log(a);
fn();
})();//执行10
fn111
//两个函数可以互不影响
递归函数 递归循环
定义:函数自己调用自己 记住:写递归时,必须给一个出口 (给一个条件让递归停止 ),否则就是死循环,无限死递归;
var count=0;
function fn(){
console.log("fn"+count)
count++;
if(count<5){ //递归出口
fn();
}
}
fn();//执行 fn0
fn1
fn2
fn3
fn4
求一个数的阶乘
第一种方法:for循环
var total = 1;
for(var i=1;i<=5;i++){
total*=i;
}
console.log(total);
第二种方法:递归 用的少,它也属于循环的一种,能用for循环就不要用递归。
function fn1(num){
if(num==1){
return 1;
}
return num*fn1(num-1);
}
var res=fn
简单认识对象
js里对象:是一种复杂数据类型,也是键值对。 对象 :键名是自定义的
一、对象的定义
1.字面量来定义:大括号包裹 "{键名1:'键值1',键名2:'键值2',键名3:'键值3'}";
键名一般不加引号
var obj={
name:"小小",
age:20,
sex:"女",
height:"178cm",
}
console.log(obj);// 执行结果{name: "小小", age: 20,sex:女, height: "178cm"}
- 通过内置构造函数来创建对象
var obj=new Object();// Object就是js里的内置构造函数 预定义
obj.name="小小";
obj.age=20;
obj.sex="男";
obj.heignt="178cm";
console.log(obj);//执行结果{name: "小小", age: 20,sex:女, height: "178cm"}
对象的操作 *****
对象其实也是一种数据,操作就包括 修(修改) 增(增加) 删(删除) 查(数据的获取)
一、对象的查询,获取对象里的键值。
var obj={
name:"小小",
age:20,
sex:"女",
height:"178cm",
}
var res=obj.name;//第一种查询不需要加引号
console.log(res);//执行 小小
var res1=obj["name"];//第二种查询需要加引号
console.log(res1);//执行 小小
二 、修改和添加。 语法 :1.对象.键名 = 要修改的值 ; 2. 对象['键名'] = 要修改的值
var obj={
name:"小小",
age:20,
sex:"女",
height:"178cm",
}
//方式一:修改名字为 王小
obj.name="王小";
//方式二:修改名字为 王小
obj["name"]="王小";
//在对象里添加一项新内容 hobby="足球"
obj.hobby="足球";//方式一
obj["hobby"]="足球";
总结:通过语法.和[""]都可以新增或者修改对象,原对象找不到的属性就是增加,找得到的就是修改操作。
三、删除
删除对象里的某个值 ;语法 delete 对象.键名
var obj={
name:"小小",
age:20,
sex:"女",
height:"178cm",
}
delete obj.height;//删除obj对象里的身高
console.log(obj);//执行{name: "小小",age: 20,sex:女}
对象的长度
对象没有长度,但是通过循环可以获取对象的具体长度。
注意区别于数组的长度 来
//数组的长度
var arr = "小李","小王","小小"];
console.log( arr.length);//执行 3
//对象的长度难道可以这样获取??
var obj = {
name:"小刘",
age:20,
height:"178cm"
}
console.log(obj.length);//执行 undefined 显示不对 不能这样写
怎么才能获取对象的长度???
//对象循环 for... in...
var obj = {
name:"小刘",
age:20,
height:"178cm"
}
var count=0;
for(var k in obj){
count++;
//console.log(k,obj); //键名和对象
//console.log("键名",k); // 键名 name 键名 age 键名 height
// console.log("键值",obj[k]) ; //键值 小刘 键值 20 键值 178cm
}
console.log("对象的长度是:"+count);//对象的长度是:3
//总结 : 对象的长度用for...in...,用循环来统计
对象的注意点
一、对象的键名/下标/索引:不能重复 都是独一无二的;键值可以重复;
name: "张三",
键名/下标/索引 键值
二、对象的键值可以是任何类型
var obj = {
name:"小小",
age:20,
fn:function(){
console.log("我的名字是"+obj.name+";我的年龄是"+obj.age);
}
}
//1.获取 obj里的fn函数;
console.log(obj.fn);//可以拿到fn这个函数
console.log(obj.age);//20
//2.获取对象里的函数且执行这个函数
obj.fn();//可以执行函数 我的名字是小小;我的年龄是20
var obj = {
arr:[1,2,3],
fn:function(){
console.log("fn")
},
name:"张三",
age:20,
hobby:{
one:"篮球",
two:"足球",
},
}
console.log(obj.arr);//获取数组
obj.fn();//执行里面的函数
console.log(obj.age);//获取年龄
三 、复杂数据类型 比较的问题 ,相同的值比较都是false 存储地址各不相同
复杂数据类型(对象,数组,函数)比较 ,是因为在内存里所有的复杂数据类型存的都是一个新的内存地址;所有复杂数据类型里不要比较两个值是不是一样的,这样不准确。
//定义一个学生对象 ,对象里有学员的信息(年龄,性别,身高)还有一个fn方法 ,调用这个fn方法 可以打印出学员的信息;
var student={
age:20,
sex:"男",
height:"178cm",
fn:function(){
//方式一
//console.log("年龄是:"+student.age+" 性别是:"+student.sex+"身高是:"+student.height)
}
//方式二 用this它是js内置的一个变量 这的this就相当于是定义的这个student对象;
//console.log("年龄是:"+student.age+" 性别是:"+this.sex+"身高是:"+this.height)
}
}
student.fn();
数组
数组: 有序的数据集合
数组创建方式一: 字面量创建 用的较多
var arr = ["老张","老王","老刘"];
console.log(arr);//(3) ["老张","老王","老刘"]
数组的操作
//数组基本操作
var arr = ["老张","老王","老刘"];
// 0 1 2
//1.获取
console.log(arr[i])
//2.添加或者修改
arr[4]="老李"//新增,但3没有会生成一个empty //(5) ["老张","老王","老刘", empty, "老李"]
arr[1]="老李"//修改
一、pop:删除数组的最后一项
语法:数组.pop() (arr.pop()); 1. 会删除原来的数组。2.返还值是删除的那个元素
var arr = ["老张","老王","老刘"];
var res=arr.pop();
console.log(arr)//删除后的剩余数组 执行(2)["老张","老王"]
console.log(res)//返还的值 是被删除的最后一个键名//执行结果就是 老刘
二、push: 添加在数组的最后一项
语法: 数组.push("要添加到最后的值"); 1.会改变原本的数组 2. 返还值是新添加数组的长度
var arr = ["老张","老王","老刘"];
var res=arr.push("老李");
console.log(arr);//添加后的新数组 执行(4)["老张","老王","老刘","老李"]
console.log(res);//添加之后数组的长度 4
三、shift 删除第1项元素(也是下标是0的元素);
语法 : 数组.shift();1. 会改变原本的数组; 2.返还值是删除的元素
var arr = ["老张","老王","老刘"];
var res = arr.shift();
console.log(arr);//删除第一项后的数组 执行(2)["老王","老刘"];
console.log(res);//删除的键名 老张
四、unshift 往第一项添加内容
语法 : 数组.unshift("添加的元素");1.会改变原本的数组 2. 返还值是添加之后的数组长度;
var arr = ["老张","老王","老刘"];
var res=arr.unshift("老李");
console.log(arr);// (4)["老李","老张","老王","老刘"];
console.log(res);// 4
五、splice:在指定位置添加或者删除数组的元素
语法 :数组.splice(要添加或者删除索引值,要删除的个数,要添加的值);1.会改变原本的数组 2. 返还值是删除的元素(数组形式)
1、删除
var arr = ["老张","老王","老刘"];
var res=arr.splice(0,1);
//小括号这里0表示从第一项开始,1表示删除的个数
// 删除功能 : 第一个参数是要开始删除的索引值;第二个参数是删除的个数 ;删除就不需要第三个参数
console.log(arr);//删除了第一项 老张 //执行(2)["老王","老刘"]
console.log(res);//删除的元素 ["老张"]
2、添加
var arr = ["老张","老王","老刘"];
//索引 0 1 2
var res=arr.splice(1,0,"老李");//表示从二项为新增的值
//var res1=arr.splice(4,0,"老李");//4>2了,但凡超过原数值的键名,都是加在最后一项,且没有empty出现。打印arr 都是(4)["老张","老王","老刘","老李"];
console.log(arr);//(4)["老张","老李","老王","老刘"];
console.log(res);//[] 是个空数组
3、替换
var arr = ["老张","老王","老刘"];
//索引 0 1 2
var res=arr.splice(1,1,"老李");//删掉索引是1的值,又在此添加了一个值,等同于替换
console.log(arr);//(3)["老张","老李","老刘"]
console.log(res);//删除的元素 ["老王"]
六 、reverse 反转数组
var arr = ["老张","老王","老刘"];
//索引 0 1 2
var res= arr.reverse();
console.log(res);// (3)["老刘","老王","老张"];
console.log(arr);//同上执行反转之后的数组(3)["老刘","老王","老张"];
七、join: 把数组通过特殊符号连接成字符串
语法 :数组.join("连接字符"); 1. 不会改变原来数组 2. 返还值是新的字符串
var arr = ["老张","老王","老刘"];
//索引 0 1 2
var str = arr.join("-");
console.log(str);//老张-老王-老刘
console.log(arr);//原来的数组不变 (3)["老张","老王","老刘"]
var arr = ["老张","老王","老刘"];
var str = arr.join("");
console.log(str);//转成字符串类型 老张老王老刘
未完待续,明天见。。。