//arguements:是一个函数的内置的特殊的对象参数,可以获得所有实参
//利用arguements写函数
//比较一组数中谁最大
/* function getMax() {
max=arguments[0];
for(var i=1;i<arguments.length;i++){
if (arguments[i]>max){
max=arguments[i];
}
}
return max;
}
var result=getMax([2,3,4,6,8,10,90]);
console.log(result); */
//函数案例
//翻转数组
/* function reverse(arr){ //reverse翻转
var newArr=[];
for(var i=arr.length-1;i>=0;i--){
newArr[newArr.length]=arr[i];
}
return newArr;
}
var result=reverse([2,4,5,6,7]);
console.log(result); */
//冒泡排序
/* function sort(arr){ //sort
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; //别忘了return写在循环外面!!!
}
var result=sort([2,5,1,8,3]);
console.log(result); */
//利用函数判断闰年
/* function isRunYear(year){
var flag=false; //首先定义一个flag
if(year%4==0 && year%100!=0 || year%400==0){
flag=true; //当满足条件时,flag变为tre
}
//不满足条件时,flag没有执行if语句,则还是false
return flag;
}
console.log(isRunYear(2000));//返回true
console.log(isRunYear(1999));//返回false */
//函数调用函数
//例
/* function fn1(){
console.log(111);
fn2(); //依次执行,先执行fn2()
console.log('hello');
}
function fn2(){
console.log(222);
}
fn1(); */
//案例:输入年份,输出这一年2月份有多少天
/* function backDay(){
var year=prompt('请你输入年份');
if(isRunYear(year)){ // 调用判断闰年的函数isRunYear,如果返回结果为true则执行if语句
alert('这一年是闰年,2月份有29天');
}else{
alert('这一年是平年,2月份有28天');
}
}
backDay(); //调用函数
function isRunYear(year){ //单独写的判断闰年的函数
var flag=false; //首先定义一个flag
if(year%4==0 && year%100!=0 || year%400==0){
flag=true; //当满足条件时,flag变为tre
}
//不满足条件时,flag没有执行if语句,则还是false
return flag;
} */
//函数的其他声明方式: 函数表达式(匿名函数) 也可以传递参数 变量名=function(){} //变量存的不是值而是函数
/* var fun=function(){
console.log('函数表达式');
}
fun();//fun为变量名 不是函数名 */
//js作用域: 代码名字在某个范围内才起作用和效果 目的是为了提高程序的可靠性,更重要的是减少命名冲突
//js的作用域(es6)之前:(1)全局作用域(整个script标签或者一个js文件中的),(2)局部作用域(在函数内部的)
//变量的作用域:全局变量(整个script标签中都能使用),局部变量(只能在函数内部使用的) 函数形参也是局部变量
//!!⭐特殊情况:在函数内部,如果没有声明一个变量而是直接赋值,这个变量算作全局变量
/* function fn(){
var num=20;
num1=10;
}
fn();
console.log(num1); //num1打印出来了
console.log(num); //num报错 */
//全局变量与局部变量比较:全局变量只有浏览器关闭后才会销毁,比较占内存;局部变量在程序执行完之后就销毁了,比较节省内存,所以一般更喜欢使用局部变量
//(3)块级作用域(es6新增的):用{}括起来的区域里起作用的,现阶段js没有块级作用域
//作用域链:在函数里有嵌套函数的时候,内部函数是可以调用外部函数的,当内部函数要调用外部的变量时,采取链式查找,也就是一级一级往外找,第一次查找到变量了就执行,就不会再往外查找了(类似于就近原则),这个结构就称之为作用域链
//js解析 js引擎运行分为两步:预解析;代码执行
//1.
//(1)预解析⭐⭐(面试常考) js引擎会把js里面所有的var function 提升到当前作用域的最前面
//然后才是代码执行:按照代码书写顺序从上往下执行
//(2)预解析分为变量预解析(变量提升)和函数预解析(函数提升)
//变量提升:就是把变量声明提升到当前作用域的最前面,不提升赋值操作
//比如
/* console.log(num);
var num=10; //打印结果为undefined,如果顺序执行应该会报错,但并没有报错,只是说num的值是未定义
//原因如下:因为进行了预解析,所以变量声明被提前了,就如一下代码顺序
var num;//预解析:变量提升
console.log(num);//代码顺序执行
num=10;//顺序执行,先执行了打印,所以没获取到10这个值 */
//再比如
/* fun();
var fun=function(){
console.log(22);
} //结果是报错
原因如下:预解析,变量提升,顺序变为以下:
var fun; //此处声明的是变量
fun(); //根本没有这个函数,调用肯定会出错 !!!⭐ 所以一般把调用函数表达式写在赋值函数后面
fun=function(){
console.log(22);
} */
//函数提升
/* fn();
function fn(){
console.log(11);
} //虽然把函数调用写在了前面,但结果是正确的,成功打印了11,原因是预解析,函数提升了,先把function fn(){}执行了才执行的其他代码 */
//案例
/* var num=10;
fun();
function fun(){
console.log(num);
var num=20;
} */ //结果是:undefined
// 原因如下:
// 执行顺序实际为:
/* var num; //变量提升
function fun(){ //函数提升
var num; //变量提升
console.log(num);
num=20;
}
num=10;
fun(); */ //执行顺序:定义num,跳过函数,num=10,调用函数,函数里先定义了num未给值,执行打印num,num取最近的变量(作用域链查找),最近的变量就是被提前的num变量,然而num只是被声明并没有被赋值,所以打印的结果是undefined;最后才执行num=20;
//经典面试题:
/* 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=b=c=9; //!!⭐注意此处并不是集体声明赋值的意思 集体声明赋值是用逗号隔开:var a=9,b=9,c=9;
// 而此处var a=b=c=9 的意思相当于 var a=9; b=9; c=9; 注意,只有a是用var声明赋值了的,而b,c并没有用var来声明,是直接赋值了的,函数里直接赋值的变量当全局变量来看!所以,此处的b,c是全局变量
//所以实际顺序应该为:
var a;
a=b=c=9;//b,c直接赋值
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
f1();
console.log(c);//9
console.log(b);//9
console.log(a);//局部变量无法在外部使用,会报错 */
//对象
//1、在js中,对象是一组无序的相关属性和方法的集合,所有事物(具体的,不是一大类,比如苹果、明星属于大类不属于对象)都是对象,例如字符串、数值、数组、函数等
//对象由属性和方法组成 属性:事物的特征(常是名词) 方法:事物的行为(常是动词) 比如一部手机,它的大小颜色还有重量就是属性,打电话、发短信、砸核桃就是方法
//为什么需要对象?
//保存单个值时可以用变量,保存一组值时可以用数组,但当要保存一套完整信息比如一个人的名字、性别、年龄、身高、体重时用数组不是很好区分,使用对象可以更直观更方便更清晰地保存信息,结构也更清晰 比如,person.name保存名字,person.age保存年龄等等
//创建对象的三种方式
//1、利用字面量创建对象:{}
//属性或方法采取键值对的形式 键 属性名 :值 属性值
/* var obj={
uname:'张三',//名字属性
age:18, //年龄属性
sex:'男', //性别属性
sayHi:function(){ //方法
console.log('Hi~'); //注意!:多个属性和方法之间用逗号隔开 方法后面跟的匿名函数
}
}
//使用对象
//调用对象属性 对象名.属性名 比如 obj.uname . 理解为‘的’
console.log(obj.uname);
//调用对象属性 对象名['属性名'] !别忘了引号''
console.log(obj['age']);
//调用对象方法 对象名.方法名() 比如 obj.sayHi() !别忘了小括号
obj.sayHi();//调用 */
//案例
/* var dog={
uname:'可可',
type:'阿拉斯加犬',
age:5,
color:'brown',
skill:function(){
console.log('bark!bark! show Film');
}
}
console.log(dog.age,dog.uname,dog.color,dog.type);
dog.skill(); */
//变量、属性、函数、方法区别
//变量与属性的相同点:都是用来存储数据的
//变量与属性的不同点:变量需要单独声明,并且在使用的时候需要写明变量名,单独存在;属性在对象里不需要声明,使用的时候要写对象名.属性名
//函数与方法的相同点:都是实现某种功能
//函数与方法的不同点:是单独声明 并且调用是 函数名() 单独存在 ; 方法调用是 对象.方法()
//2.利用new Object创建对象
/* var obj=new Object(); //创建了一个空对象
obj.uname='张三';
obj.age=18;
obj.sex='男';
obj.sayHi=function(){
console.log('Hi~');
} //利用等号赋值的方法添加对象属性和方法 属性方法之间以 ; 隔开
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
*/
//作业
/* var obj=new Object();
obj.uname='鸣人';
obj.sex='男';
obj.age=19;
obj.skill=function(){
console.log('影分身术');
}
console.log(obj.uname,obj.sex,obj.age);
obj.skill(); */
//3.利用构造函数创建对象(好处:可以创建多个对象,之前两个方法只能创建一个对象)
//可以利用函数的方法重复相同代码——构造函数
//构造函数就是把我们对象里一些相同的属性和方法抽象出来封装到函数里面
//
/* function Star(uname,sex,age){ //形参 //构造函数名字首字母大写!!!⭐
this.name=uname; //!!!⭐要使用this this表明是当前对象
this.sex=sex;
this.age=age; //构造函数不需要return
this.sing=function(song){ //实参传到方法的形参
console.log(song);
}
}
var zhangsan= new Star('张三','男',18); //实参 !!!调用构造函数必须用new⭐
console.log(typeof zhangsan); //得到的类型是对象object
console.log(zhangsan.name,zhangsan.age,zhangsan.sex);
zhangsan.sing('开心歌'); //实参 调用方法
var lisi=new Star('李四','男',20); //只要调用构造函数就创建一个对象
console.log(lisi.name,lisi.age,lisi.sex); //构造函数可以实现批量生产
lisi.sing('难过歌'); */
//属性和方法前必须加this
//作业
/* function Hero(uname,type,blood){
this.name=uname;
this.type=type;
this.blood=blood;
this.attak=function(at){
console.log(at);
}
}
var lianpo= new Hero('廉颇','力量型','500血量');
lianpo.attak('近战');
console.log(lianpo.name,lianpo.type,lianpo.blood);
var houyi=new Hero('后裔','射手型','100血量');
houyi.attak('远程');
console.log(houyi.name,houyi.type,houyi.blood); */
//构造函数与对象的区别
//构造函数:如Star(),抽象了对象的公共部分,封装到了函数里面, 泛指一大类
//创建对象:如new Star(),特指某一个,通过new关键字创建对象的过程我们也称为 对象实例化
//new关键字
//new在执行时会做四件事:
/* 1.在内存中创建一个空的对象
2.让this指向这个新对象
3.执行构造函数里的代码,给这个新对象添加属性和方法
4.返回这个新对象(所以构造函数不需要return) */
//遍历对象 利用for in
/* var obj={
uname:'张胜男',
sex : '男',
age:19,
fn:function(){}
}
for(var k in obj){
console.log(k); //k 返回属性名!!!⭐
console.log(obj[k]); //obj[k]返回属性值!!!⭐
} */
//作业
//1.创建对象
/* var computer={
color:'red',
weight:'1000g',
brand:'apple',
model:'2t1',
use:function(){
console.log('看电影','听音乐','打游戏','敲代码');
}
}
for(var k in computer){
console.log(computer[k]);
}
console.log(computer.use()); */
//
/* function Car(weight,height,color){
this.weight=weight;
this.height=height;
this.bgcolor=color;
this.click=function(click){
console.log(click);
}
}
var tsl=new Car('2.2m','1.6m','red');
console.log(tsl.weight,tsl.height,tsl.bgcolor);
tsl.click('click'); */
//翻转函数
/* function reverse(arr){
var arr1=[];
for(var i=arr.length-1;i>=0;i--){
arr1[arr1.length]=arr[i];
}
return arr1;
}
var res= reverse([2,3,6,5,1,8,9]);
console.log(res); */
//简易计算器
/* var start=prompt('欢迎使用简易计算器:\n1.加法计算\n2.减法运算\n3.乘法运算\n4.除法运算\n5.退出')
if (start==1){
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
num=parseFloat(num1)+parseFloat(num2);
alert(num);
}else if(start==2){
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1-num2);
}else if(start==3){
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1*num2);
}else if(start==4){
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1/num2);
} */
//升级版:可以实现循环输入(也就是算出一组值后会回到开头选择计算器的页面,可以重复计算)
for(var i=1;i<=5;i++){
var start1=prompt('欢迎使用简易计算器:\n1.加法计算\n2.减法运算\n3.乘法运算\n4.除法运算\n5.退出');
start=parseFloat(start1);
// var num1=prompt('请输入第一个数值');
// var num2=prompt('请输入第二个数');
switch(start){
case 1:
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
num=parseFloat(num1)+parseFloat(num2);
alert(num);
break;
case 2:
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1-num2);
break;
case 3:
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1*num2);
break;
case 4:
var num1=prompt('请输入第一个数值');
var num2=prompt('请输入第二个数');
alert(num1/num2);
break;
}
if (start==5){
break;
}
}