js基础
函数
重点掌握
如何声明,如何调用,如何写函数
声明
1 关键字
function 函数名(参数){函数体}
2 函数表达式
var 变量名 = function(参数){函数体}
调用
函数名(实际参数)
、
写函数的步骤
- 先写过程
- 分析过程中,哪些可以作为函数体(在过程中,总是不变的),哪些可以作为参数(在过程中,不断改变的)
- 按照语法写函数的格式
- 有没有返回值
- 调用
函数的返回值
三种情况
- 没有return --> undefined
- 有return,没有跟数据--->undefined
- 有return,并且有跟着数据-->跟着的数据
return作用
- 修改函数的返回值
- 终止函数的执行
函数的参数
形参,实参
形参的值发生变化,不影响实参的值
可以有省略参数的机制
一般实现由2种方式:
arguments对象
-
参数默认值
函数的执行过程
- 函数里面的代码,如果没有调用时不会执行的
- 函数里面可以调用另外的函数
- 函数在调用的时候,会回到声明的位置执行,执行完毕之后,又会回到调用位置,继续执行
- 函数在执行的时候,会发生参数的传递,按照顺序传递
匿名函数
没有名字的函数------匿名函数无法单独存在
不定个数的参数的处理方式
- 在js中,实参个数可以和形参个数不一致
- 在函数中,因为形参和实参个数可以不一致,准备了一个东西,( arguments对象)可以得到所有的实参
- arguments对象里面可以得到所有的实参
- arguments对象可以通过下标得到实参,但是注意一个问题: arguments不是数组
- arguments无法再函数外面使用
function getSum(a,b){
var sum = 0;
for(var i=0;i<arguments.length;i++){
sum += arguments[i]
}
return sum
}
console.log(getSum(10,20));
console.log(getSum(10,20,30));
特别注意
#### 什么东西可以作为变量的值 - 数据
- 数据都是有类型的
- 函数可以作为变量的值 --> 函数也是一种数据
- 通过typeof 函数名 ==》 函数也是一种数据类型
什么东西可以作为函数的参数
- 只要是归数据类型管的都可以作为参数
- 函数也可以作为参数
- 在一个函数a中,以参数形式传入的另一个函数b,作为参数的函数b,是可以在函数a中被调用的
- 在一个函数中,以参数形式进入到该函数的另一个参数,在执行的时候,称之为:回调函数
什么可以作为返回值
数据都可以,函数也是数据的一种,函数也可以作为返回值
逻辑运算符的短路运算规则
逻辑或(||)
- 如果左边的隐式转换结果是true,整个式子的结果就是左边的表达式的结果
- 如果左边的隐式转换的结果是false,直接返回右边
逻辑与(&&)
如果左边为true,返回右边
如果左边为false,直接返回左边
给每个参数设置一个默认值,如果没有传递进来,就使用默认值参与运算
a = a || 0;
一般在调用以参数传入的函数的时候,需要先判断这个东西是不是函数
f && f();
匿名函数
使用场景:
-
函数表达式
var fn = function(){}
可以作为参数
-
自调用函数
- 自动调用 - 声明完毕之后,立刻调用
- 自己调用 - 自己调用自己(递归)
自调用函数
语法:(function(形参){})(实参);
作用:自调用函数的作用就是形成一个封闭的作用域,把里面的变量保护起来
预解析和作用域
看看函数两种声明方式的区别
函数表达式必须在完成声明之后,才可以调用
预解析
js在执行之前,会先预解析
预解析会把当前作用域下的变量声明和函数的声明提升到当前作用域的最顶端,但是变量的赋值,函数的调用都还在原来的位置,还是原来的顺序
简单说:
在执行之前: 把 变量和函数 的声明 提升到 {当前} 作用域 的最顶端
作用域
作用的范围,有效的范围
指的是变量和函数的有效范围
作用域链
多层作用域关系--作用域链
变量或者函数的访问规则
- 如果内部作用域有自己的变量,会优先使用自己的
- 如果自己内部没有,会跨过当前作用域,往上级作用域查找
- 如果上级也没有,就往上级的上级,以此类推,直到全局作用域
- 如果全局作用域也没有,报错
内置对象
获取当前的系统日期和时间
内置日期对象的多个方法
- 获取年份 getFullYear()
- 获取月份 getMonth() 但是要注意,返回的结果是0表示一月,1表示二月
- 获取日份 getDate() 得到一个月中的某一天
- 获取小时 getHours() 得到小时
- 获取分钟 getMinutes() 得到分钟
- 获取秒 getSeconds() 得到秒
- 获取当前的毫秒 getMilliseconds()
- 获取时间戳:getTime() 从1970年1月1日到现在的所经过的毫秒数
Math对象
// 随机取值函数
// floor向下取整,ceil向上整
function getRandom(n,m){
return Math.floor(Math.random() * (m-n + 1) + n);
}
数组对象
数组的方法
- reverse() 可以将数组翻转
- splice() 删除数组的元素
- 数组对象.splice(从哪里开始删除,一共要删除多少个);
- push() 从数组的末尾添加一个或者多个元素
- pop() 从数组的末尾删除一个元素,并返回该元素
- unshift() 从前面添加一个或者多个元素
- shift() 从前面删除一个元素,并返回
- sort() 排序
- 数组.sort();
- 有默认的排序规则
- 有默认的排序规则
- 需要传递一个排序规则函数
- 该函数要有两个参数
- 返回值是两个参数的差
arr.sort(function(a,b){
return a - b;
});
注意
- 一般不会出现函数名和变量名重名的情况 -- 除非是面试题
- 如果能做到变量名有意义和函数名有意义,就不会出现重名
小细节
- 预解析,会优先解析函数,再解析变量
- 变量声明比函数声明更优先
- 如果函数名和变量名重名,就会覆盖
字符串
根据索引获取对应的字符
字符串[索引]
字符串.charAt(索引)
把多个字符串连接起来------ 使用+运算符
截取字符串中的某些字符--- 字符串.slice(从哪里开始,到哪里结束) , 不包括结尾,如果没有指定末尾,会包含从开始到末尾的所有的字符
根据字符查找对应的索引---- 字符串.indexOf(字符) 如果找得到就得到对应的数字,如果找不到,就得到-1
-
替换字符串中的想要替换的字符,但是不会修改原来的字符
字符串.replace(旧的字符,永远替换的新字符)
-
分割字符串为数组----- 字符串.split("切割符");
var str = "a|b|c|d"; var arr = str.split("|"); console.log(arr);
-
将数组连接成字符串
数组.join("连接符")
var str = "a|b|c|d"; // var arr = str.split("切割符"); var arr = str.split("|"); console.log(arr); // var s = arr.join("|"); // console.log(s);
对象
面向对象思想
把编程中遇到的所有的功能,都认为是某个对象的方法
- 先获取对象(自己创建或者原来就有的)
- 指挥对象做事情------使用对象的属性或者方法
面向对象思想的三大特征: 封装性 , 继承性 , 多态性
什么叫对象
从编程的角度讲: 对象就是属性和方法的集合
属性和方法的表示方式: 键值对
在编程中,就把事物的特征叫做对象的属性,把事物的行为叫做方法
内置对象
date math array string -- js原本就给我们封装好的一堆的代码的高度封装
自定义对象
-
创建对象
- new Object() 构造函数法
- {} 字面量法
-
给对象设置属性或者调用对象的属性
- 不同的对象具有不用的能力,当我们想要使用方法的时候,必须找对对象
- 定义的对象如果想要他会做某些事情,或者具备某些特征,就要给他添加属性和方法
- 语法:
- 对象.属性 = 值;
- 对象.方法 = function(){实现功能的过程}
-
使用对象的属性和方法
- 对象.属性
- 对象.方法(参数)
-
字面量表示法的快速声明对象的键值对的方式
{
属性:值,
属性:值,
方法名:function(){}
}
-
工厂模式
function createComputer(color,brand,price,weight){ var computer = new Object(); computer.color = color; computer.brand = brand; computer.price = price; computer.weight = weight; computer.open = function(){ console.log('等灯等灯'); } computer.close = function(){ console.log('叮咚'); } return computer; } var c1 = createComputer('red','apple','¥19998','3kg'); var c2 = createComputer('black','联想','¥9998','6kg'); console.log(c1); console.log(c2);
将工厂模式变成自定义构造函数
1、改名字 把动词+名词结构 ---> 名词结构,首字母大写
2、把new Object去掉 还有return 去掉
3、把之前代表对象的变量,改成this
// 更加建议使用自定义构造函数 -- 简洁,更加符合编程人员的审美
function Computer(color,brand,price,weight){
this.color = color;
this.brand = brand;
this.price = price;
this.weight = weight;
this.open = function(){
console.log('等灯等灯');
}
this.close = function(){
console.log('叮咚');
}
}
// 在使用自定义构造函数创建对象的时候,记得一定要new
var c1 = new Computer('red','apple','¥19998','3kg');
console.log(c1);
c1.close()
new的秘密
原生构造函数(Array,Date,Object)
自定义构造函数(Computer)
-
都有一个关键字new
new做的工作
- 创建一个对象,把对象赋值给this
- 执行构造函数的代码
- 把对象返回调用构造函数的位置
- 当构造函数创建对象,都需要new
this(重点)
this在构造函数中指向实例对象
普通函数中this指向window
-
作为对象的方法-----this指向调用该函数的对象
作为函数内部的this,谁调用该函数,this就是谁
注意
普通函数的角色
所有window的属性和方法在使用的时候,都可以把window省略
对象
属性和方法
console.log();//直接在控制台中打印输出
-
遍历对象
把每个键值对都拿出来
for(var 键名 in 要遍历的对象){
}
一般:
for(var key in obj){
}
-
访问属性的第二种方式
访问属性:
对象.属性 ----》 点操作符
对象[属性名的字符串]----》 键的方式访问
删除/添加对象的属性
添加属性:
对象.属性 = 值;
删除:
delete 只能用于删除的对象的属性
delete 对象.属性
值类型和引用类的区别
简单类型(值类型)
复杂类型(引用类型)
值类型和引用类型的异同:
1 值类型存储在栈空间
引用类型存储在堆空间,堆空间的地址会存储在栈空间上
2 当我们以一个变量作为另一个变量的值的时候,其实是把栈空间中的值复制一份
3 当我们堆形参进行修改的时候
如果实参是值类型,形参和实参就互不影响
如果实参是引用类型,形参会影响实参