arguments的使用
//arguments的使用 只有函数才有arguments对象 而且每个函数都内置好了这个arguments
function fn() {
console.log(arguments);//里面存储了所有传递过来的实参
console.log(arguments.length);
console.log(arguments[2]);
//我们可以按照数组的方式遍历arguments
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
fn(1, 2, 3);
fn(1, 2, 3, 4, 5);
//伪数组并不是真正意义上的数组
//1.具有数组的length属性
//2.按照索引的方式进行存储
//3.它没有真正数组的一些方法:pop() push() 等等
利用函数求任意个数的最大值
//利用函数求任意个数的最大值
function getMax() {//arguments=[1,2,3]
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3));
console.log(getMax(1, 2, 3, 4, 5));
console.log(getMax(1, 2, 3, 444, 5, 100));
利用函数封装的方法翻转任意一个数组
//利用函数翻转任意数组
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 3, 4, 6, 9]);
console.log(arr1);
var arr2 = reverse(['red', 'pink', 'blue']);
console.log(arr2);
利用函数封装的方式对数组排序——冒泡排序
//利用函数封装的方法冒泡排序
function sort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
var arr2 = sort([11, 7, 22, 999]);
console.log(arr2);
利用函数判断闰年`
//我写的,为啥是undefined?
function judge(year) {
year = prompt('请输入年份:');
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
alert(console.log(year + '是闰年'));
} else {
alert(console.log(year + '不是闰年'));
}
return year;
}
console.log(judge());
//老师写的 利用函数判断闰年
function isRunYear(year) {
//如果是闰年,我们返回true,否则返回false
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
函数案例
//函数是可以相互调用的
function fn1() {
console.log(11);
fn2();//在fn1函数里面调用了fn2函数
}
fn1();
function fn2() {
console.log(22);
}
案例-用户输入年份,输出当前年份2月份的天数
//用户输入年份,输出当前年份2月份的天数
//如果是闰年,则2月份是29天,如果是平年,则2月份是28天
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) {//调用函数需要加小括号
alert('当前年份是闰年2月份有29天');
} else {
alert('当前年份是平年2月份有28天');
}
}
backDay();
//判断是否为闰年的函数
function isRunYear(year) {
//如果是闰年,我们返回true,否则返回false
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
函数的两种声明方式
//函数的两种声明方式
//1.利用函数关键字自定义函数(命名函数)
function fn() {
}
fn();
//2.函数表达式(匿名函数)
//var 变量名 = function () { };
//与var num = 10;相似
var fun = function (aru) {
console.log('我是函数表达式');
console.log(aru);
}
fun('Pink老师');
//(1)fun是变量名 不是函数名
//(2)函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
//(3)函数表达式也可以进行传递参数
JavaScript作用域
//1.javascript作用域:就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性 更重要的是减少命名冲突
//2.js的作用域(es6)之前,全局作用域 局部作用域
//3.全局作用域:整个script标签 或者是一个单独的js文件
var num = 10;
console.log(num);
//4.局部作用域(函数作用域) 在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
function fn() {
//局部作用域
var num = 20;
console.log(num);
}
fn();
函数在不同的作用域下变量名不会有影响,在相同的作用域下变量名冲突就会有麻烦
变量的作用域
变量作用域的分类
全局变量
局部变量
全局变量和局部变量的区别
//变量的作用域:根据作用域的不同我们变量分为全局变量和局部变量
//1.全局变量:在全局作用域下的变量
//注意:如果在函数内部没有声明直接赋值的变量也属于全局变量
var num = 10;//num就是一个全局变量,在全局下都可以使用
console.log(num);
function fn() {
console.log(num);
}
fn();
//2.局部变量 在局部作用域下的变量,后者在函数内部的变量就是局部变量
///注意:函数的形参也可以看做是局部变量
function fun() {
var num1 = 10;//num1就是局部变量,只能在函数内部使用
num2 = 20;
}
fun();
// console.log(num1);
console.log(num2);
//3.从执行效率来看全局变量和局部变量
//(1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
//(2)局部变量,当我们的程序执行完毕就会销毁,比较节约内存资源
作用域
JS没有块级作用域
//js中没有块级作用域,JS的作用域:全局作用域,局部作用域,现阶段我们的js没有块级作用域,
//我们js也是在es6的时候新增的块级作用域
//块级作用域{} if{} for{}
//java
/* if (xx) {
int num = 10;
} */
//外面的是不能调用num的
if (3 < 5) {
var num = 10;
}
console.log(num);
作用域链
一层一层往上查找,采取就近原则
//作用域链:内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链,一层一层往上查找,采取就近原则
//全局作用域
var num = 10;
//局部作用域
function fn() { //外部函数
var num = 20;
function fun() { //内部函数
console.log(num);
}
fun();
}
fn();
案例分析
站在目标出发,一层一层往外查找
//案例1:结果是几?
function f1() {
var num = 123;
function f2() {
console.log(num);//站在目标出发,一层一层的往外查找
}
f2();
}
var num = 456;
f1();
//案例2:结果是几?
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a);//4
console.log(b);//22
}
}
}
fn1();
JavaScript预解析
预解析
//1问
console.log(num);
//2问
console.log(num);//undefined 坑1
var num = 10;
//相当于执行了以下代码
var num;
console.log(num);
num = 10;
//3问
fn();
function fn() {
console.log(11);
}
//相当于
function fn() {
console.log(11);
}
fn();
//4问
fun();//报错 坑2
var fun = function () {
console.log(22);
}
//函数表达式调用必须写在函数表达式的下面
//相当于执行了以下代码
var fun;
fun();
fun = function () {
console.log(22);
}
//1.我们JS引擎运行js分为两步:预解析 代码执行
//(1)预解析 js引擎会把js里面所有的var 还有function提升到当前作用域的最前面
//(2)代码执行 按照代码书写的顺序从上往下执行
//2.预解析分为 变量预解析(变量提升)和函数预解析(函数提升)
//(1)变量提升 就是把所有的变量声明提升到当前作用域最前面 不提升赋值操作
//(2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
预解析案例
//预解析案例
//案例1
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
//相当于执行力以下操作
var num;
function fun() {
var num;
console.log(num);
var num = 20;
}
num = 10;
fun();
//案例2
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
//相当于以下代码
var num;
function fn() {
var num;
console.log(num);
num = 20;
console.log(num);
}
num = 10;
fn();
//undefined 20
//案例3
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
//相当于以下代码
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
//undefined 9
//案例4(经典面试题)
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
//相当于以下代码
function f1() {
var a;
a = b = c = 9;
//相当于var a=9;b=9;c=9;b和c直接赋值 没有var声明 当全局变量
//集体声明 var a=9,b=9,c=9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
//9 9 9 9 9 报错
JavaScript对象
什么是对象?
对象是一个具体的事物,是一个实实在在存在的事物
为什么需要对象
创建对象的三种方式
利用字面量创建对象
变量 属性 函数 方法总结
//利用对象字面量创建对象 {}
//var obj = {}; //创建了一个空的对象
var obj = {
uname: '张三疯',
age: 18,
sex: '男',
sayHi: function () {
console.log('hi~');
}
}
//(1)里面的属性或者方法我们采取键值对的形式,键 属性名:值 属性值
//(2)多个属性或者方法中间用逗号隔开的
//(3)方法冒号后面跟的是一个匿名函数
//2.使用对象
//(1)调用对象的属性,我们采取 对象名.属性名.我们理解为 的
console.log(obj.uname);
//(2)调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
//(3)调用对象的方法 sayHi 对象名.方法名 千万别忘记添加小括号()
obj.sayHi();
//变量、属性、函数、方法的区别
//变量和属性的相同点 他们都是用来存储数据的
var num = 10;
var obj = {
age: 18,
fn: function(){
}
}
function fn(){
}
console.log(obj.age);
console.log(age);
//变量 单独声明并赋值 使用的时候直接写变量名 单独存在
//属性 在对象里面的不需要声明的 使用的时候必须是 对象.属性
//2.函数和方法的相同点 都是实现某种功能 做某件事
//函数是单独声明并且调用的 函数名() 单独存在的
//方法在对象里面 调用的时候 对象.方法()
利用new Object创建对象
跟我们前面学的new Array()原理一致
//利用new Object创建对象
var obj = new Object();//创建了一个空的对象
obj.uname = '张三疯';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function () {
console.log('hi~');
}
//(1)我们是利用等号=赋值的方法 添加对象的属性和方法
//(2)每个属性和方法之间用分号结束
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
利用构造函数创建对象
为什么需要构造函数
//我们为什么需要使用构造函数
//就是因为我们前面两种创建对象的方式一次只能创建一个对象
var ldh = {
uname: '刘德华',
age: '55',
sing: function () {
console.log('冰雨');
}
}
var zxy = {
uname: '张学友',
age: 58,
sing: function () {
console.log('李香兰');
}
}
//因为我们一次创建一个对象,里面很多的属性和方法是大量相同的,我们只能复制
//因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为构造函数
//又因为这个函数不一样,里面封装的不是普通代码,而是对象
//构造函数就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
//利用构造函数创建对象
//我们需要创建四大天王的对象 相同的属性:名字 年龄 性别 相同的方法:唱歌
//构造函数的语法格式
/* function 构造函数名(){
this.属性=值;
this.方法=function(){}
}
new 构造函数名(); */
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function (sang) {
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男');//调用函数返回的是一个对象
// console.log(typeof ldh);
console.log(ldh.name);
console.log(ldh['sex']);
ldh.sing('冰雨');
var zxy = new Star('张学友', 19, '男');
console.log(zxy.name);
console.log(zxy.age);
zxy.sing('李香兰');
//1.构造函数名字首字母要大写
//2.我们构造函数不需要return就可以返回结果
//3.我们调用构造函数必须使用new
//4.我们只要new Star()调用函数就创建一个对象 ldh {}
//5.我们的属性和方法前面必须添加this
构造函数和对象的联系
//构造函数和对象
//1.构造函数 明星 泛指的某一大类 它类似于Java语言里面的类(class)
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function (sang) {
console.log(sang);
}
}
//2.对象 特指 是一个具体的事物 刘德华=={name: '刘德华', age: 18, sex: '男', sing: ƒ}
var ldh = new Star('刘德华', 18, '男');//调用函数返回的是一个对象
console.log(ldh);
//3.我们利用构造函数创建对象的过程我们也称为对象的实例化
new关键字
//new关键字执行过程
//1.new构造函数可以在内存中创建了一个空的对象
//2.this就会指向刚才创建的空对象
//3.执行构造函数里面的代码给这个空对象添加属性和方法
//4.返回这个对象
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function (sang) {
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男');
遍历对象属性
for…in 语句用于对数组或者对象的属性进行循环操作
//遍历对象
var obj = {
name: 'pink老师',
age: 18,
sex: '男',
fn: function () {
}
}
/* console.log(obj.name);
console.log(obj.age);
console.log(obj.sex); */
//for in遍历我们的对象
/* for(变量 in 对象){
} */
for (var k in obj) {
console.log(k);//k 变量 输出,得到的是属性名
console.log(obj[k]);//obj[k]得到的是属性值
}
//我们使用for in里面的变量,我们喜欢写k 或者key
小结