欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript基础知识_笔记

程序员文章站 2022-06-25 12:13:24
JS的特点:解释型语言动态语言基于原型的面向对象基本输出:alert(‘这是第一个js代码’);//弹出警告框document.write(“啦啦啦啦啦啦啦”);//可以向body输出一个内容console.log(“向控制台输出一个内容”);//控制台输出内容基本语法:JS注释:多行注释,注释内容不会被执行,但是可以在源代码中查看。(养成良好的代码注释习惯);JS中严格区分大小写;每一条语句都以;结尾。(如果不添加分号,浏览器会自动添加,但那还是会消耗一些系统资源,有时....

JS的特点:

  • 解释型语言
  • 动态语言
  • 基于原型的面向对象

基本输出:

alert(‘这是第一个js代码’);//弹出警告框
document.write(“啦啦啦啦啦啦啦”);//可以向body输出一个内容
console.log(“向控制台输出一个内容”);//控制台输出内容

基本语法:

  • JS注释:多行注释,注释内容不会被执行,但是可以在源代码中查看。(养成良好的代码注释习惯);
  • JS中严格区分大小写;
  • 每一条语句都以;结尾。(如果不添加分号,浏览器会自动添加,但那还是会消耗一些系统资源,有时候会加错分号)。
  • JS会忽略多个空格和换行;

字面量和变量

  • 字面量,都是些不可变的量:1,2,3,4,…,字面量都是可以直接使用的,但一般不会直接使用;
  • 变量:可以用来保存字面量,变量的值可以直接改变,变量更加方便我们使用,所以自爱开发中都是通过变量保存一个字面量,而且很少直接使用字面量;
声明变量:var a;

标识符

  • 在JS中所有的可以由我们自主命名的都可以称为是标识符;例如:变量名、函数名、属性名;
  • 命名一个标识符时需遵守如下的规则:
    1.标识符中可以含有字母、数字、_、KaTeX parse error: Double subscript at position 11: ,如:var a_1_̲ =12;
    2.不能以数字开头;
    3.不能是ES中的关键字或保留字;
    4.标识符一般都采用驼峰命名法:首字母小写,每个单词的开头字母大写,其余小写;
  • JS底层标识符时实际上是采用的UNicode编码,所以理论上讲,所有的Utf-8中含有的内容都可以作为标识符;

数据类型

  1. String:字符串
  2. Number:数值
  3. Boolean:布尔值
  4. Null:空值
  5. Undefined:未定义
  6. Object:对象
  • String,number,boolean,null,undefined属于基本数据类型;
  • Object属于引用数据类型;
    #####String字符串
    1.在JS字符串中需要使用引号引起来
    2.使用双引号或者单引号都可以,但是不要混着用;
    3.引号不能嵌套,双引号里不能放双引号,单引号里不能放单引号;
    4.在字符串中可以使用\作为转义字符,当表示一些特殊符号是可以使用\进行转义:
    " 表示 "
    ’ 表示 ’
    \n 表示换行
    \t 制表符
    \ 表示 \
Number
  • 在JS中所有的数值都是Number类型,包括整数和浮点数;
  • JS中可以表示的数字的最大值:
    Nmuber.MAX_VALUE : 1.7976931348623157e+308
    如果使用Number表示的数字超过了最大值,则会返回Infinity表示正无穷;
  • NAN是一个特殊的数字,表示 “Not A Number”;使用typeof检查一个NaN会返回number;
    var a = NaN; typeof a 返回number;
    var a = “NaN”; typeof a 返回string;

可以使用一个运算符typeof来检查一个变量类型
语法:typeof 变量
检查字符串时会返回string,
检查数值时会返回number.
console.log(typeof a);

  • 在JS中整数的运算基本可以保证精确;
  • 如果使用JS进行浮点运算,可能得到一个不精确的结果,所以千万不要使用JS进行对精确度要求比较高的运算;
    #####Boolean 布尔值
    布尔值只有两个,主要用来做逻辑判断
  • true 表示真
  • false 表示假
Null

Null类型的值只有一个,就是null;
null这个值专门用来表示一个为空的对象;
typeof 检查null 返回"Object";

Undefined

Undefined类型的值只有一个,就是undefine;
当声明一个变量但并没有赋值时,它的值就是undefined;

var a = undefined;
console.log(typeof a);
//返回undefined;

强制类型转换

指将一个数据类型强制转换为其他的数据类型

类型转换主要指,将其他的数据类型转换为String Number Boolean;
  1. 将其他类型转换为String:
    方式一:调用被转换数据类型的toString()方法,该方法不会影响到原变量,它将转换的结果返回;
    toString(16)转化进制;
    如:var a =255; a = a.toString(16); // 16
    注意:null和undefined这两个值没有tostring()方法,若是调用则报错;
var a = 123;
a = a.toString();
console.log(typeof a);//返回string
console.log(a);
	方式二:调用String()函数,并将被转换的数据作为参数传递给函数;
	使用String()函数做强制类型转换时,对于Number 和 Boolean实际上就是调用的toString()方法,但是对于null 和 undefined不会调用toString()方法,它会将null直接转换为"null",将undefined转换为"undefined",都转换成字符串类型。
var b = 456;
b = String(b);//转换b,参数就是b
console.log(typeof b);//返回string
console.log(b);
  1. 将其他类型转换为Number:
    方式一:使用Number()函数,
    1. 字符组 - -> 数字
    (1)如果是纯数字的字符串,则直接将其转换为数字:
	var a = "123";
	a = Number(a);
	console.log(typeof a);	//number
	console.log(a);	//123

(2)如果字符串中有非数字的内容,则转换为NaN:

var a = "abc";
a = Number(a);
console.log(typeof a);	//number
console.log(a);	//NaN

(3)如果字符串是一个空串或者是一个全是空格的字符串,则转换为0:

var a = " ";
a = Number(a);
console.log(typeof a);	//number
console.log(a);	//0

2.布尔 --> 数字

  • true 转成 1
  • false 转成 0

3.null --> 数字

  • null 转成 0

4.undefined --> 数字

  • undefined 转成 数字NaN

方式二:这种方式专门用来对付字符串,
parseInt()把一个字符串转换为一个整数,能够获取字符串中的有效的整数内容取出来,然后转换为Number。
注意:如果对非String使用parseInt()或者parseFloat()它会先将其转换为String,然后再操作。

var a = "123px";
a = parseInt(a);
console.log(typeof a);// number
console.log(a);	//123
parseFloat()把一个字符串转换为一个浮点数;
var a = "123.456px";
a = parseFloat(a);
console.log(typeof a);//number
console.log(a);//123.456
  1. 将其他类型转换为Boolean:
    方式一:使用Boolean()函数:
    (1). 数字 --> 布尔:
    除了0和NaN,其余的都是true
    (2). 字符串 --> 布尔:
    除了空串,其余的都是true
    (3).null 和 undefined 都是false
    (4).对象也会转换为true

    具体举例:

var a = 123;
a = Boolean(a);
console.log(typeof a);
console.log(a);
a = 0;//false
a = Indinity; //true
a = NaN ;//false
a = "hello"; //true

方式二:隐式类型转换:
为任意数据类型做两次非运算,即可将其转换为Boolean值

var b =10;
b = !!b; //true
console.log(typeof b); //boolean

补充: 其他进制的数字
1.在JS中,如果需要表示16进制的数字,则需要以0x开头:

	var a = 0x10;
    console.log(a);// 16

2.如果需要表示8进制的数字,则需要以0开头:

	var a = 070;
    console.log(a);// 56

3.如果需要表示2进制的数字,则需要以0b开头,但是不是所有浏览器都支持:

	var a = 0b10;
    console.log(a);// 2

4.可以在parseInt()中传递第一个第二个参数,来指定数字的进制:

	var a = "070";
    var b = parseInt(a, 8);
    var c = parseInt(a, 10);
    console.log(b);	//56
    console.log(c);	//70

运算符

运算符也叫操作符,通过运算符可以对一个或多个值进行运算,并获取运算结果,比如typeof就是运算符,可以来获得一个值的类型,它会将该值的类型以字符串的形式返回。
如 number string boolean undefined object 这些都是字符串的形式,只不过是用来描述类型。

var a =123;
var result = typeof a;
console.log(result);//number
console.log(typeof result);//string
  1. 算数运算符: + - * / %
    当对非Number类型的值进行运算时,会将这些值转换为Number然后再运算。
    任何值和NaN做运算都是NaN;
    “+”:
  • 可以对两个值进行加法运算,并将结果返回;

  • 如果对两个字符串进行加法运算,则会做拼串;(两个字符串拼接在一起) ;

      var str = "你好" + "我是" + "啦啦啦啦啦";
    console.log(str); //你好我是啦啦啦啦啦
    
  • 任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串的操作。

       var str = 123 + "1";
          console.log(str); // 1231
    
  • 任何值和字符串相加都会转换成字符串,做拼接操作;利用这一特点,将任意数据类型转换为String,只需将任意的数据类型 + 一个 ""即可将其转换为String,这是一种隐式的类型转换,由浏览器自动转换,实际上也是调用String()函数;

  •   var c = 123;
      c = c + "";
      console.log(typeof c); //string
      console.log("c = "+c); //c = 123
      
      //从左往右进行运算
       var c = 1 + 2 + "3";    
       var re = "1" + 2 + 3;  
       console.log(typeof c);
       console.log("c = "+c); // c =33
       console.log("re = "+re);//re = 123
    

"-":

  • 可以对两个值进行减法运算,并将结果返回
    var a;
    a = 100 - “1”;
    console.log(a); //99
    “*”:

  • 可以对两个值进行乘法运算;

       a = 2 * "8"; //16
       a = 2 * undefined; //NaN
       a = 2 * null; //0
    

“/”:

  • 可以对两个值进行乘法运算;
 a = 4 / "2"; // 2

任何值做 - * /运算都会自动转换为Number;
我们可以利用这一特点做隐式类型转换,可以通过一个值 -0、 *1、 /1来将其转换为Number,原理和Number()函数一样,使用起来更加简单;
“%”:

  • 取模运算

2.一元运算符,只需一个操作符:
“+ ”正号
+ 正号不会对数字产生任何影响

	  var a = 123;
       a = +a;
       console.log(a); //123

“- ”负号

  • 可以对数字进行负号的取反

对于非Number类型的值:它会将先转换为Number,然后在运算;可以对其他数据类型使用+,来将其转换为Number,它的原理和Number()函数一样;

a =true;
a = -a;
console.log(a);

a = 1 + + "2" + 3; // +"2" = 2;所以就是a=1+2+3
b = 1 + "2" +3;
console.log("a = "+a); //a=6
console.log("b = "+b); //b=123

自增:通过自增可以使变量在自身的基础上增加1;
自增分成两种:i++ 和 ++i;

  • 无论是i++还是++i,都会使原变量值立即自增1;
  • 不同的是i++ 和 ++i的值不同:
    • i++的值等于原变量的值(自增前的值),先输出再计算

        var i = 1;
        console.log(i++); //1
        console.log("i = "+i); //i=2
      
    • ++i的值等于原变量的新值(自增后的值),先计算再输出

    •   var i = 1; 
        console.log(++i); //2
        console.log("i = "+i); //i = 2
        
         var a = 1;     
         console.log(a++); //2
        console.log(++a); //3
        		
        var b = 20;
        //20 + 22 + 22 = 64
         var result = b++ + ++b + b;
         console.log("result = "+result); //64
      

自减:通过自减可以使变量在自身的基础上减1;
分成两种:i-- 和 --i

  • 不同的是i-- 和 --i的值不同:(原理同自增);

练习:

	var n1=10, n2 = 20;
    var n = n1++;   //n1 = 11, n1++ = 10

    console.log('n='+n);    //10
    console.log('n1='+n1); //11

    n = ++n1;   //n =12 ++n1 = 12
    console.log('n='+n); //12
    console.log('n1='+n1); // 12

    n = n2--; //n2=19 n=20
    console.log('n='+n); //20
    console.log('n2='+n2); //19

    n = --n2; //n = 18 --n2=18
    console.log('n='+n); //18
    console.log('n2='+n2); //18

3.逻辑运算符
三种逻辑运算符:!、&&、||

  • !:如果对非布尔值进行运算,则会将其转换为布尔值,然后再取反,所以我们可以利用该特点来将一个其他的数据类型转换为布尔值,可以为任意一个数据类型取两次反,来将其转换为布尔值,原理和Boolean()函数一样。

      var b =10;
      b = !b; // false
      b = !!b; // true
      console.log(typeof b); //boolean
    
  • &&:两个值中只要有一个值为false就返回false;
    JS中的“与”为短路与,如果第一个值为false,则不会看第二个值。若第一个值为true,则会检查第二个值;

  • ||:两个值中只要有一个值为true就返回true;
    JS中的“或”为短路或,如果第一个值为true,则不会检查第二个;若第一个值为false,则会检查第二个值;

&& || 非布尔值的情况:

  • 对于非布尔值进行与或运算的,会先将其转换为布尔值然后再运算,并且返回原值。

  • 规则:
    与运算:
    如果第一个值为true,则必然返回第二个值;
    如果第一个值为false,则直接返回第一个值;

      //true && true
      //若两个值都为true,则返回后边的值
      var res = 1 && 2;
      console.log("res = "+res); // 2
      var res = 2 && 1;
      console.log("res = "+res);// 1
      var res = 0 && 1;
      console.log("res = "+res); // 0
      var res = 1 && 0;
      console.log("res = "+res); // 0
      		
      //false && false
      var res = NaN && 0;
      console.log("res = "+res);// NaN
      var res = 0 && NaN;
      console.log("res = "+res);// 0
    

    或运算:
    如果第一个值为true,则直接返回第一个值;
    如果第一个值为false,则返回第二个值;
    res = NaN || 1; // 1
    res = “” || “hello”; // hello
    4.赋值运算符:+=
    5.关系运算符:>、>=、<、<=:如果关系成立,则返回true;
    比较两个字符串时,比较的是字符串的字符编码。
    比较字符编码时是一位一位进行比较,
    如果两位一样,则比较下一位,所以借用它来对英文进行排序;
    比较两个字符串数字大小时,一定要注意转型;(“5” --> +“5”)

	res = "abc" < "b";
	//先是比较a与b的大小,若a<b,则比较b与b的大小,b<b不成立,返回false;

在字符串中使用转义字符输入unicode编码:\u四位编码;

console.log("\u2620"); //☠

6.相等运算符:比较两个值是否相等;相等返回true,否则返回false;

  • 使用 == 来做相等运算;
    当使用 ==来比较两个值时,如果值的类型不同,则会自动进行类型转换,然后再比较;

      console.log("1" == 1); //true
      //undefined 衍生自null
      console.log(undefined == null); //true
      
      NaN不和任何值相等,包括它本身
      console.log(NaN == NaN); //false
      可以通过isNaN()函数来判断一个值是否是NaN,是就返回true;
    
  • !=:不相等返回true,相等返回false;

  • 不相等也会对便利进行自动的类型转换,如果转换后相等它也会返回fasle;

  • ===:判断两个值是否全等,和相等类型;

    • 不同的是:如果两个值的类型不同,直接返回false;
  • !==:判断两个值是否不全等,和不等类型;

    • 不同的是:如果两个值的类型不同,直接返回true;
      7.条件运算符:
  • 语法:条件表达式?语句1:语句2

  • 执行流程:条件运算符在执行时,首先对条件表达式进行求值,如果该值为true,则执行语句1,并返回执行结果,如果为false,则执行语句2,并返回执行结果。

      var max = a > b ? a : b;
      //判断a b c中的最大值
      max = max > c ? max : c;
    

8.运算符的优先级:优先级越高越先计算,若是一样高,则从左往右计算;
图中越上优先级越高:
JavaScript基础知识_笔记

	 /* 
        分析:
        如果||的优先级高,或者两个一样高,则应该返回3
        如果&&的优先级高,则应该返回1
    */
	var res = 1 || 2 && 3;
    console.log("res = "+ res);// 1
	当不清楚优先级高低时,可以用括号改变运算顺序

语句:{}:代码块

语句分类:
1.条件判断语句:if{…} else if{…}else{…}

prompt()可以弹出一个提示框,该提示框中会有一个文本框
用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数
该字符串将会作为提示框的提示文字
用户输入的内容将会作为函数的返回值返回,可以定义一个变量来接收该内容
var score = prompt("请输入小明的期末成绩:");
alert(score);

2.条件分支语句:switch() { case:}
3.循环语句:

	var a = prompt();
    for(var i=0; i < a; i++){
        document.write(i + "<br/>");
    }
			//输入 3;
			//输出:0
			//	  1
			//	  2
  • while语句在执行时:先对条件表达式进行求值判断,如果为true则继续执行循环体,执行完毕继续对表达式进行判断,如果为fasle则终止循环。

  • do…while循环:先执行循环体,执行完毕后对while后的条件表达式进行判断,如果为true继续执行,若为false,则终止循环。

  • for语句:for(初始表达式; 条件表达式; 更新表达式)
    ①执行初始表达式,初始化变量
    ②执行条件表达式,判断是否执行循环,
    ③若为true,则执行循环,若为false,则终止;
    ④执行更新表达式,执行完毕继续重复②

      for( ; ; ){ //死循环
      }
    

练习:判断输入的数是否是质数

	var num = prompt("请输入一个数字:");
     if(num < 0)
     {
         alert("不合法~");
     }
     else
     {
         //默认当前num是质数
         var flag = true;
         
        for(var i =2; i < num; i++)
        {
            if(num % i== 0 )
            {
                flag = false;
            }
        }
        if(flag)
        {
            alert(num + "是质数");
        }
        else{
            alert(num + "不是质数");
        }
     }
//九九乘法表
	for(var i=1; i<10; i++)
   {
       for(var j = 1; j <= i; j++)
       {
           document.write( i + "*"+ j +" ="+i*j);
		 // document.write( "<span>" + i +" * "+ j  +" = "+ i*j +"</span>");
           document.write("    ");
       }
       document.write("<br />");
   }

break 和 continue 关键字

  1. break关键字可以用来退出switch或循环语句;
    - 不能在if语句中使用break和continue;
    - break关键字会立即终止离它最近的那个循环语句;
    -当想结束指定的循环语句时,
    可以为循环语句创建一个label,来标识当前的循环
    label:循环语句
    使用break语句时,可以在break后跟着一个label,
    这样break将会结束指定的循环,而不是最近的 ;

     outer:
      for(var i=0; i<5; i++)
    	{
      	  console.log("@外层循环"+i);
        	for(var j=0; j<5; j++)
        	{	
          	  break outer;
            	console.log("内层循环:"+ j);
        	}
    	}
    

2.continue关键字:立即结束当前循环,同样默认对离它最近的那个循环语句起作用;

补充:

 	//测试以下程序的性能
	//在程序开始之前,开启计时器
	//console.time("计时器的名字")可以用来开启一个计时器
	//它需要一个字符串作为参数,这个字符串将会作为计时器的标识
    console.time("test");
    for(var i=2; i<=100; i++)
    {
        var flag = true;
        for(var j=2; j<Math.sqrt(i); j++)
        {
            if(i%j == 0)
            {
                flag = false;
            }
        }
        if(flag)
        {
            //console.log(i);
        }
    }
    console.timeEnd("test");

Object 对象

对象属于一种符合的数据类型,在对象中可以保存多个不同数据类型的属性;
对象的分类:

  1. 内建对象
    - 由ES标准中定义的对象,在任何的ES的实现中都可以使用
    - 比如:Math String Number Boolean Function Object…
    2.宿主对象
    - 由JS的运行环境提供的对象,目前来讲主要由浏览器提供的对象
    - 比如:BOM DOM
    3.自定义对象:由开发人员自己创建的对象

    (1)创建对象:
     在对象中保存的值称为属性
    (2)向对象添加属性:
    语法: 对象.属性名 = 属性值
        var obj = new Object();
     	obj.name = "张三";
    	 obj.gender = "男";
     	obj.age = 20;
    
     	console.log(obj);
    	//{name: "张三", gender: "男", age: 20}
    
    (3)读取对象中的属性:
    	语法:对象.属性名
    	console.log(obj.gender); //男
    (4)修改对象的属性值:
    	语法:对象.属性值 = 新值
    (5)删除对象的属性值
    	语法:delete 对象.属性值
    

对象更像一个容器,可以装不同的属性

属性名:

对象的属性名不强制要求遵守标识符的规范,但是我们还是尽量按照标识符的规范去做。

如果使用特殊的属性名,不能采用 . 的方式来操作,需要使用另一种方式,读取时也要采取这种方式;

	语法:对象[“属性名”] = 属性值
	如:obj["123"] = 789;
	读取: console.log(obj["123"]);
	(一般情况下来说,属性名不能以数字开头,除非你真的想用,就采取以上方法)

	使用 [ ]这种形式去操作属性更加的灵活
	在[ ]中可以直接传递一个变量,这样变量值是多少就会读取哪个属性;
obj["123"] = 789;
var n = "123";       
console.log(obj[n]); //789
//根据不同的变量取不同的值,这种方式更灵活
属性值:
  • JS对象的属性值,可以是任意的数据类型,甚至也可以是一个对象

      obj.test = "hello";
      obj.test = 123;
      obj.test = true;
      obj.test = null;
    
      var obj = new Object();
      var obj2 = new Object();
      obj2.name = "李四";
      
      //将obj2设置为obj的属性
      obj.test = obj2;
      console.log(obj.test); // {name: "李四"}
      console.log(obj.test.name); //李四
    
  • in 运算符:通过该运算符可以检查一个对象中是否含有指定的属性,如果有则返回true,没有返回false;

    • 语法:“属性名” in 对象
//检查属性是否存在
console.log("test2" in obj); //没有 false
  • JS的变量都是保存到栈内存中的,
    • 基本数据类型的值直接在栈内存中存储;
      值与值之间是独立存在的,修改一个变量不会影响其他的变量
    • 对象保存在堆内存中,每创建一个新对象,就会在堆内存中开辟出一个新的空间,两变量保存的是对象的内存地址(对象的引用),如果两个对象保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响。
		var a = 123;
		var b = a;
		a++;
		console.log("a = "+a); //124
		console.log("b = "+b); //123
		//变量a分配了一个内存,b也分配了一个内存,两个都拥有独立的内存地址,当a的值发生改变并不影响b的值

JavaScript基础知识_笔记

   var obj = new Object();
    obj.name = "李四";

    var obj2 = obj;
    console.log(obj.name);//李四
    console.log(obj2.name);//李四
	//当name的值发生改变时,这两个输出都会随之改变,
	//当obj2设置为null时,相当于与obj断了联系,obj不会受到影响

JavaScript基础知识_笔记

/* 
 比较两个基本数据类型的值时,就是比较值,
 而比较两个引用数据类型时,它是比较对象的内存地址,
 如果两个对象是一模一样的,但是地址不同,它也会返回false;
*/
var c =10;
var d =10;
console.log(c == d);//true
 var obj3 = new Object();
 var obj4 = new Object();
 obj3.name = "王五";
 obj4.name = "王五";
 console.log(obj3 == obj4); //false
 //相当于是长得很像的双胞胎,但本质上是不一样的

总结:基本数据类型保存的是值,引用数据类型保存的是地址

对象字面量
  • 使用对象字面量来创建一个字面量
    • 使用对象字面量:可以在创建对象时,直接指定对象中的属性

语法:{属性名 :属性值,属性名 :属性值…};

   对象字面量的属性名可以加引号也可以不加,建议不加,
	如果要使用一些特殊的名字,必须加引号;
	
	属性名和属性值是一组一组的名值对结构
   名和值之间使用 :连接,多个名值之间使用 ,隔开
   如果一个属性之后没有其他属性了,就不要写逗号;

函数

  • 函数也是一个对象
  • 函数中可以封装一些功能,在需要时可以执行这些功能;
  • 使用typeof检查一个函数对象时会返回function;
  • 函数中的代码会在函数调用的时候执行
    调用函数语法,函数对象();
    当调用函数时,函数中封装的代码会按顺序执行
  • 使用函数声明来创建一个函数

语法:function 函数名([形参1,形参2…形参N]){
语句…
}

	function fun2()
    { 
        console.log("这是我的第二个函数~~");
        alert("哈哈哈哈哈");
    }
    fun2();
    //console.log(fun2);

立即执行函数
函数定义完, 立即被调用,这种函数叫做立即执行函数
立即执行函数往往只会执行一次

	(function(){
      alert("我是一个立即执行函数~~~");
  })();
  • 使用函数表达式来创建一个函数

var 函数名 = function ([形参1,形参2…形参N]){
语句…
} var fun3 = function(){
console.log(“我是啦啦啦啦啦啦啦啦~”);
};//相当于赋值函数
fun3();

补充:
函数也可以成为对象的属性,如果一个函数作为一个对象的属性保存,那么我们称这个函数是这个对象的方法,调用函数就调用对象的方法;

var obj = {
            name: "张三",
            age : 20,
            gender : "男"

       };
       obj.sayName = function(){
           console.log(obj.name);
       };

       obj.sayName();//张三
函数参数
  • 定义一个用来求两个数和的函数
    可以在函数()中来指定一个或多个形参;
    多个形参之间使用,隔开
   		function sum(a, b){
            console.log(a+b);
        }
        sum(123,456);
		// 在调用函数时,可以在()指定实参
    	// 实参将会赋值给函数中对应的形参
			
		/*
			调用函数时解析器不会检查实参的类型
        所以要注意,是否有可能接收到非法的参数,
		如果有可能则需要岁参数进行类型的检查
		函数的实参可以是任意的数据类型
		*/
		sum(123,"hello");
			
		/* 
        调用函数时解析器不会检查实参的数量
        多余的实参不会被赋值
		如果实参的数量少于形参的数量,则没有对应的实参的形参将是undefined;
        */
        sum(123,345,"hello",true);//486
		sum(123);  //NaN
  • 实参可以是任意数据类型,也可以是一个对象,

当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递

 function sayHello(o){
            //console.log("o = "+ o);
            console.log("我是"+o.name+ ",我今年" +o. age + ",性别" + o.gender);
        }
        sayHello("张三",20,"男");
     
        var obj = {
            name : "张三",
            age:20,
            gender : "男"
        };
        
        sayHello(obj);
  • 实参可以是一个对象,也可以是一个函数
 	function fun(a){
            //console.log("a ="+a);
            a(obj);
    }
    fun(sayHello);//直接调用函数也可
			
	function mianji(r){
        return 3.14 * r * r;
    }

    fun(mianji);
	/*输出:a =function mianji(r){
        return 3.14 * r * r;
    }
	函数对象,相当于直接使用函数对象;
	*/
			
    fun(mianji(4));
	//输出:a =50.24;调用函数,相当于使用的函数的返回值

通俗的说,mianji()函数可以比喻成可以做冰激凌的机器,调用mianji()相当于直接做出一个冰激凌给别人,返回最终结果,而调用mianji相当于是直接把整台机器给别人,返回函数本身。

返回值
  • return 后的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果
  • 如果return语句后不跟任何值就相当于返回一个undefined。
  • 如果函数中不写return,则也会返回undefined。
枚举对象中的属性
  • 使用 for … in 语句

语法:
for(var 变量 in 对象)
{
}

  for .. in 语句对象中有几个属性,循环体就会执行几次
 var obj = {
        name: "张三",
            age : 20,
            gender : "男",
            address : "长沙"
      };
for(var n in obj){
                console.log("属性名:"+n);
                console.log("属性值:"+obj[n]); 
	//根据变量取对象的值用[ ],用 obj.n 是获取不到obj里的属性值,因为不存在n这个属性;
            }
作用域

指一个变量的作用范围
在JS中有两种作用域:
1.全局作用域
(1)直接编写在script标签中的JS代码,都在全局作用域
(2)全局作用域在页面打开时创建,在页面关闭时销毁
(3)在全局作用域中有一个全局对象window,它代表的事一个浏览器窗口,它由浏览器创建我们可以直接使用
在全局作用域中:

	①创建的变量都会作为window对象的属性保存。
var a = 10;
console.log(a);// 10; 相当于console.log(window.a)
	②创建的函数都会作为window的方法保存
function fun(){
    console.log("我是fun函数");
}
window.fun();//window才是最大套娃~~
	③全局作用域中的变量都是全局变量,在页面的任意部分都可以访问的到;

2.函数作用域
(1)调用函数是创建函数作用域,函数执行完毕后,函数作用域销毁
(2)每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
(3)函数作用域中可以访问到全局作用域的变量,
在全局作用域中无法访问到函数作用域的变量

var a = 10;
function fun(){
		var b =8;
		console.log("a = "+a);
}
fun();    //a =10
console.log("b = "+b);//报错

(4)当在函数作用域操作一个变量时,它会现在自身作用域中寻找,如果有直接使用,若没有则向上一级作用域中寻找(就近原则);如果全局作用域依然没有找到,则会报错;

var a = 10;
function fun(){
		var b = 8;
		var a = "我是函数中的变量a~";
		console.log("a = "+a);// a = 我是函数中的变量a~
}
fun();    //a =10
console.log("a = "+a);// a = 10

(5)在函数中要访问全局变量可以使用window对象

var a = 10;
function fun(){
		var a = "我是函数中的变量a~";
		console.log("a = "+a);//我是函数中的变量a~
		function fun2(){
			console.log("a = "+window.a);// a=10;访问全	局变量
		}
		fun2();//我是函数中的变量a~
}
fun();    //a =10

(6)注意:在函数中,不使用var声明的变量都会成为全局变量;函数中定义了形参相当于声明了变量

var c =10;
function fun5(){
		console.log("c = "+c); // c =10
		c = 10;//这里的C相当于是全局变量
		d = 100;//没有设置var关键字,这里的d相当于是全局变量
}
fun5();
console.log("c = "+c);//c =10,就近原则:输出就近的全局变量C
console.log("d = "+d);// d = 100

补充:

  1. 变量的声明提前:
  • 使用var关键字声明的变量,会在所有代码执行之前被声明,(但是不会被赋值);
	console.log("a = "+a); // a = undefined
	var a = 123;
	//相当于下面这种:
	var a;
	console.log("a = "+a); //a = undefined
	a = 123;
  • 如果声明变量时不使用var关键字,则声明变量不会被提前声明;
console.log("a = "+a); //直接报错
a = 123;

2.函数的声明提前

  • 使用函数声明形式创建的函数function函数(){},它会在所有的代码执行之前就被创建,所以我们可以在函数声明提前来调用函数
	fun();
	function fun(){//函数声明会被提前创建
		console.log("我是fun函数");
	}
	//相当于下面这种
	function fun(){
		console.log("我是fun函数");
	}
	fun();

  • 使用函数表达式创建的函数不会被声明提前,所以不能再声明前调用;
	var fun2 = function (){
		console.log("我是fun2函数");
	};
	fun2();//我是fun2函数

  //而下面这种声明是不可取的
	fun2();	//报错
	var fun2 = function (){//函数表达式,不会被提前创建
		console.log("我是fun2函数");
	};

  • 在函数作用域也有声明提前的特性,使用var关键字声明的变量,会在函数中所有的代码执行之前被声明;函数声明也会在函数中所有的代码执行之前被执行;
function fun3(){
          console.log(a);//undefined
        	var a=35;
}
			
function fun3(){
		  var a;
          console.log(a);//undefined
          a=35;      
}
this

解析器在调用函数每次都会向函数内部传递一个隐含的参数

  • 这个隐含的参数就是this,this指向的是一个对象,

  • 这个对象我们称为函数执行的上下文对象,

  • 根据函数的调用方式的不太,this会指向不同的对象(this指向当前引用的对象)
    1.以函数的形式调用时,this永远都是window
    2.以方法的形式调用的,this就是调用方法的那个对象

    		function fun() {  
    			console.log(this.name);
    		}
    		 var obj1 = {
    				name : "张三",
    				sayName: fun
    		 };
    		 var obj2 = {
    				name : "李四",
    				sayName: fun
    		};
    		//obj.sayName();// this 指向 obj
    		obj1.sayName();  // 张三;this 指向obj1
    		obj2.sayName();  // 李四;this 指向obj2
    

this 的情况:
1.当以函数的形式调用时,this就是window
2.当以方法的形式调用时,谁调用方法this就是谁
3.当以构造函数的形式调用时,this就是新创建的那个对象

使用工厂方法创建对象
  • 使用工厂方法创建的对象,使用的构造函数都是Object,所以创建的对象都是Object这个类型,就导致我们无法区分出多种不同类型的对象
 function createPerson(name, age, gender){ //传参
            var obj = new Object();

            //向对象中添加属性
            obj.name = name;
            obj.age = age;
            obj.gender = gender;
            obj.sayName = function(){
                alert(this.name);
            }
            return obj;	//返回对象
       }
       var obj2 = createPerson("小陈", 20, "女");
       var obj3 = createPerson("小赵",20,"女");

       console.log(obj2);//{name: "小陈", age: 20, gender: "女", sayName: ƒ}
       console.log(obj3);//{name: "小赵", age: 20, gender: "女", sayName: ƒ}
构造函数
  • 创建一个构造函数,专门用来创建Person对象的
    构造函数就是一个普通的函数,创建方式和普通函数没有区别
    不同的是构造函数习惯上首字母大写
  • 构造函数和普通函数的区别就是调用方式的不同
    普通函数直接调用,构造函数需要new关键字来调用
var per = Person();//普通函数
var per = new Person();//构造函数
  • 构造函数的执行流程:
    1.立即创建一个新的对象
    2.将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
    3.逐行执行函数中的代码
    4.将新建的对象作为返回值返回
	function Person(){
            this.name = "张三";//this指新建的对象
            this.age = 20;
            this.gender = "男";
      }
      var per = new Person();//构造函数
      console.log(per);
	//上面这种方式会把属性值写死,可以利用传参会更灵活些
	function Person(name, age, gender){
            this.name = name;//this指新建的对象
            this.age = age;
            this.gender = gender;
      }
      var per = new Person("张三", 22, "男");//构造函数的实例
      console.log(per);
  • 使用同一个构造函数创建的对象,我们称为一类对象,也将构造函数称为一个类。
    我们将通过一个构造函数创建的对象,称为是该类的实例

构造函数就是类,构造函数创建的对象就是实例
使用instanceof可以检查一个对象是否是一个类的实例
如果是则返回true,否则返回false

语法:对象 instanceof 构造函数

var per = new Person("张三", 22, "男");//构造函数
console.log(per instanceof Person);// true 
所有的对象都是Object的后代,任何对象和Object做
instanceof检查是都会返回true
原型对象
  • 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype

    • 如果函数作为普通函数调用prototype没有任何作用
      当函数以构造函数的形式调用时,它所创建的对象都会有一个隐含的属性,指向该构造函数的原型对象
    • 我们可以通过__proto__来访问该属性
      原型对象就相当于公共区域,所有同一个类的实例都可以访问到这个原型对象
    • 我们可以将对象*有的内容,统一设置到原型对象中
      作个比喻:对象相当于教学楼,实例是里面的教室,而原型则相当于厕所,属于公共区域!
  • 当我们访问对象的一个属性或者方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用

  • 以后我们创建构造函数时,可以将这些对象共有的属性和方法,同统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了;

	function MyClass(){

		}
	//向MyClass的原型中添加属性a
	 MyClass.prototype.a = 123;
	 MyClass.prototype.sayHello = function (){
					console.log("Hello");
	 };      
		var mc = new MyClass();
		mc.sayHello()
		console.log(mc.a);
  • 使用in 检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
	console.log("a" in mc);	//true
  • 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性;使用该方法只有当对象自身含有属性时,才会返回true;
	console.log(mc.hasOwnProperty("a"));//fasle

原型补充:
原型对象也是对象,所以它也有原型
( 套娃开始~~ 找爷爷的爷爷)

  • 当我们使用一个对象的属性或方法时,会在自身中寻找, 自身中有直接使用,如果没有,则去原型对象中寻找,
  • 如果原型对象中有,则使用,如果没有则去原型的原型中寻找;直到找到Object对象的原型
  • Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined;
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));// true
console.log(mc.__proto__.__proto__);//Object(祖宗)
console.log(mc.__proto__.__proto__.__proto__);// null(祖宗已经到头,再往后就是空)
垃圾回收
  • 当一个对象没有任何的属性或者便利对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾,
    这种对象过多会占用大量的内存空间,导致程序运行变慢,所以必须进行清理;
  • JS中拥有自动垃圾回收机制,会自动将垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收操作;
    我们需要做的只是要将不再使用的对象设置为null即可
var obj = new Object();//obj是变量,它的值指向对象的地址
obj = null;//obj设置为ull时,此时断开了与对象的连接,该对象应被当作垃圾进行回收
数组
  • 数组也是一个对象
    它和普通对象的功能类似,也是用来存储一些值的
    不同的是普通对象是使用字符串作为属性名的,而数组是使用数字来作为索引操作元素的
  • 索引(index):从0开始的整数
  • 数组的存储性能比普通对象好,在开发中我们经常使用数组来存储一些数据
  • 向数组中添加属性
    语法 : 数组[索引] = 值
	 var arr = new Array();
	arr[0] = 0;
	arr[1] = 3;
	console.log(arr);
  • 读取数组中的元素,如果读取不存在的索引不会报错而是返回undefined
    语法:数组[元素]
	console.log(arr[0]);// 0
	console.log(arr[2]);//undefined
  • 获取数组的长度:
    1. 对于连续的数组可以用length属性获取
    语法:数组.length
	arr.length
2.对于非连续的数组,使用length会获取到数组的最大的索引+1
  • 修改length
    如果修改的length大于原长度,则多出的部分会空出来 如果修改的length小大于原长度,则多出的元素会被删除
  • 向数组的最后一个位置添加元素
    语法:数组[数组.length] = 值
	arr[arr.length] = 6

补充:

  • 使用字面量来创建数组
  • 使用字面量创建数组时,可以在创建时就指定数组中的元素
    语法:[]
	var arr = [];
	var arr = [1, 2, 3, 4];
  • 使用构造函数添加数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递
    元素之间使用,隔开
	 var arr2 = new Array(10,20,30);
  • 创建一个数组,数组中只有一个元素10
	arr = [10];
	console.log(arr[0]);// 10
  • 创建一个长度为10的数组(用的少)
	arr2 = new Array(10);
  • 数组中的元素可以是任意的数据类型,也可以是对象
	   arr = ["hello", 1, true, null, undefined];
	   console.log(arr);
	
	   var obj = {name: "张三"};
	   arr[arr.length] = obj;
	   console.log(arr[5]);
  • 可以是一个函数
	arr = [function(){alert(1)}, function () {  }];
    arr[0]();//调用第一个函数
  • 二维数组
	arr = [[1,2,3], [4,5,6],[7,8,9]];
数组的方法
  1. push()
    该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
    可以将添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的长度

     var arr = ["张三", "李四", "王五"];
     arr.push("小赵", "小陈", "小明");
     console.log(arr);// (6) ["张三", "李四", "王五", "小赵", "小陈", "小明"]
    

    该方法会将数组新的长度作为返回值返回;
    2.pop()
    该方法可以删除数组的最后一个元素,并将删除元素作为返回值返回;

     arr.pop();
     console.log(arr);// ["张三", "李四", "王五", "小赵", "小陈"]
    

3.unshift()
向数组的开头添加一个或多个元素,并返回新的数组长度
向前面加入元素以后,其他的元素会依次调整
javascript arr.unshift("小高", "小花"); console.log(arr); // ["小高","小花" "张三", "李四", "王五", "小赵", "小陈"]
4.shift()
可以删除数组的第一个元素,并将删除元素作为返回值返回
5.slice()
可以用来从数组提取指定元素
该方法不会改变元素,而是将取到的元素封装到一个新数组返回
参数:
1.截取开始的位置的索引,包含开始索引
2.截取结束的位置的索引,不包含结束索引
(第二个参数可以省略不写,此时会截取从开始索引往后所有的元素)
索引可以传递一个负值,如果传递一个负值,则从后往前计算;如 -1:倒数第一个

var arr = ["张三", "李四", "王五","小张","小赵", "小陈"];
var res= arr.slice(2, 4);
res = arr.slice(2, -1);//["王五", "小张","小赵"]
console.log(res);//["王五", "小张"]
//包括第二个,不包括第四个

6.splice()
可以用于删除数组中的指定元素
参数:
第一个:表示开始位置的索引
第二个:表示删除的数量
第三个及以后:可以传递新的元素,这些元素将会自动插入开始位置索引前边

res = arr.splice(0,2);//返回被删除的元素: 张三,李四
res = arr.splice(0,2, "小明");//["小明", "王五", "小张", "小赵", "小陈"]

练习:去除数组里重复的元素

        var arr = [1,2,3,2,2,1,3,4,2,5];

        //去除数组中重复的数字
        //获取数组中的每一个元素
        for(var i =0; i < arr.length; i++)
        {
            //获取当前元素后的所有元素
            for(var j = i+1; j < arr.length; j++)
            {
                //判断两个元素的值是否相等
                if(arr[i] == arr[j])
                {
                    //如果相等则证明出现了重复,则删除j对应的元素
                    arr.splice(j, 1);

                    //当删除了当前j所在的元素以后,后边的元素会自动补位
                    //此时将不会再比较这个元素,则需要再比较一次j所在位置的元素
                    //使j自减
                    j--;
                }
            }
        }
        console.log(arr);// [1, 2, 3, 4, 5]
数组的遍历

将数组中所有的元素都取出来
使用该方法会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回。

var arr = ["张三", "李四", "王五"];
for(var i=0; i<arr.length; i++)
{
		console.log(arr[i]);
}
练习:取出数组里年龄大于等于18的person
function Person(name, age){
            this.name = name;
            this.age = age;
            
      }
      Person.prototype.toString = function(){
          return "Person"[name = "+this.name+ ",age = "+this.age+"];
      }

      var per = new Person("张三", 18);
      var per1 = new Person("李四", 19);
      var per2 = new Person("王五", 20);
      var per3 = new Person("赵六", 20);
      var per4 = new Person("刘七", 15);
      
      //将这些person放入到一个数组中
      var perArr = [per, per1, per2,per3, per4];
      console.log(perArr);
      /* 
      创建一个函数,可以将perArr中的满18岁的Person取出来
      然后封装到一个新的数组中并返回

      arr
      形参,要提取新的数组
      */

      function getAdult(arr){
          //创建一个新的数组
          var newArr = [];

          //遍历arr 获取Person
            for(var i=0; i < arr.length; i++)
            {
                //判断Person对象的age是否大于18
                if(arr[i].age >= 18)
                {
                    //如果大于等于18,则将这个对象添加到newArr中
                    newArr.push[arr[i]];
                }
            }
          return newArr;
      }
      var res = getAdult(perArr);
      console.log(res);
forEach

一般我们都是使用for循环去遍历数组,JS中还为我们提供了一个方法,用来遍历数组;(该方法只支持IE8以上的浏览器)
foEach()方法需要一个函数作为参数
像这种函数,由我们创建但不由我们调用,我们称为回调函数
数组中有几个元素,函数就会执行几次,每次执行时,浏览器会将遍历到的元素以实参的形式传递进来,我们可以定义形参来读取这些内容
浏览器会在回调函数中传递三个参数:
第一个参数:就是当前正在遍历的元素
第二个参数:就是当前正在遍历的元素的索引
第三个参数:就是正在遍历的数组

var arr = ["张三", "李四", "王五"];
 arr.forEach(function fun(a, b, c){//(value, index, obj)
            console.log("a = "+a);
			console.log("b = "+b);
            console.log("c = "+c);
  });
	//
a = 张三
b = 0
c = 张三,李四,王五
a = 李四
b = 1
c = 张三,李四,王五
a = 王五
b = 2
c = 张三,李四,王五
数组的剩余方法
  • concat()可以连接两个或或多个数据,并将新的数组返回
    该方法不会对原数组产生影响
 var res = arr.concat(arr2, arr3, "小于");
 console.log(res);//["张三", "李四", "王五", "小张", "小赵", "小陈","小于"];
  • 该方法可以将数组转换为一个字符串
    该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
    在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
    如果不指定连接符,则默认使用,作为连接符
 	 res = arr.join();//张三,李四,王五
      res = arr.join("你好,");
      console.log(res);//张三你好,李四你好,王五
  • join()
    该方法可以将数组转换为一个字符串
    该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
    在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
    如果不指定连接符,则默认使用,作为连接符
	 res = arr.join();//张三,李四,王五
      res = arr.join("你好,");
      console.log(res);//张三你好,李四你好,王五
  • reverse()
    该方法用来反转数组(前边的去后边,后边的去前边)
    该方法会直接修改原数组
	console.log(arr.reverse());//["王五", "李四", "张三"];
  • sort()
    可以用来对数组中的元素进行排序
    也会影响原数组,默认会按照unicode编码进行排序
    即使对于纯数字的数组,使用sort()排序时,也会按照unicode编码进行排序
    所以对数字排序时,可能会得到错误的答案;
    对于数字排序:
    我们可以自己来指定排序的规则
    我们可以在sort()添加一个回调函数,来指定排序规则
    回调函数中需要定义两个形参
    浏览器将会分别使用数组中的元素作为实参去调用回调函数
    使用哪个元素调用不确定,但是肯定的是在数组中a一定在b的前面
    浏览器会根据回调函数的返回值来决定元素的顺序,
    如果返回一个大于0的值,则元素会交换位置
    如果返回一个小于0的值,则位置不变
    如果返回一个等于0的值,则认为两个元素相等,也不交换位置
 	res = arr.sort();
    console.log(res);//["a", "b", "c", "d", "e"]

   
    arr.sort();
    console.log(arr);// [11, 3, 5, 6, 8]
    //
    arr = [3,5,11,8,6,1,2];
     arr.sort(function(a,b){
        // console.log("a = "+ a);
        // console.log("b = "+ b);
        /* if(a >b ){
            return 1;
        }
        else if(a <b){
            return -1;
        }else{
            return 0;
        } */
        // 升序排列
        return a-b;

        //降序排列
       // return b - a;
     });
      console.log(arr);

本文地址:https://blog.csdn.net/qq_43216593/article/details/107448720

相关标签: WEB javascript