前端之JavaScript基础2

1.数组

所谓数组, 就是将多个元素 (通常是同一类型),按一定顺序排列放到一个集合中 , 那么这个多个元素的集合我们就称之为数组

  • 特点 : 有顺序,有长度;

  • 用途 : 存储大量的数据

  • 总结 :

    ​ 数组 : 多个元素的集合,这个集合有顺序,有长度。用途是存储大量的数据.

1.1 创建数组

1)通过 构造函数 创建数组

var arr = new Array();//创建了一个空数组
var arr = new Array(1,2,3,4);//创建了一个数组,里面存放了4个数字
var arr = new Array(4);//创建了一个数组,长度为4,里面全是空值

2)通过 数组字面量 创建数组

var arr1 = []; //创建一个空数组
var arr2 = [1, 2 , 3, 4]; //创建一个包含4个数值的数组,多个数组项以逗号隔开
var arr3 = [4]; // 创建一个数组,元素只有1个,,,元素是4

1.2 数组的长度与下标

数组的长度 : 跟字符串一样,,,数组有一个length 属性,, 指数组中存放的元素的个数 ;

var str1 = 'abc';
console.log(str1.length);

var arr = [1,3,5,8];
console.log(arr.length);

数组的下标 : 因为数组有序的,有序的就应该有自己的序号,,而这个序号就是每个元素对应的下标, 下标从0 开始 , 到 arr.length-1 结束

 var arr = ["zs", "ls", "ww"];
    arr[0];//下标0对应的值是zs
    arr[2];//下标2对应的值是ww

  var arr = ['zs','ls','ww'];

  //           0    1    2

  // 下标 :  0 开始     arr.length-1 结束     长度:3 arr.length

1.3 数组的取值与赋值

数组的取值 :

//格式:数组名[下标]
//功能:  获取数组下标对应的那个值,如果下标不存在,则返回undefined。
// 下标范围 :  0 ~ arr.length-1
var arr = ["red", "green", "blue"];
//
打印 : arr[0];//red
打印 : arr[2];//blue
打印 : arr[3];//这个数组的最大下标为2,因此返回undefined

数组的赋值 :

//格式:数组名[下标] = 值;
//如果下标有对应的值,会把原来的值覆盖,
var arr = ["red", "green", "blue"];
arr[0] = "yellow";//把red替换成了yellow
// 如果下标不存在,会给数组新增一个元素。
arr[3] = "pink";//给数组新增加了一个pink的值

// 如果下标有跨度,,中间全是empty 不合法

// 特殊 : arr[arr.length] = 值
  arr[arr.length] = '哈';  
  arr[arr.length] = '你妹';  

思考 : 如何给一个数组添加新的元素???? [重要]

  • arr[arr.length] = 值

  • arr.push(值)

1.4 数组的遍历

遍历 : 对数组的每一个元素都访问一次就叫遍历

数组遍历的基本语法:

// 传统遍历
arr[0];
arr[1]

// for遍历 1-100 的演变

// 下标 :  0  arr.length-1
//   
for(var i =0; i < arr.length; i++) {
	//数组遍历的固定结构
}

1.5 冒泡排序

 冒泡排序算法的运作如下:
//比较相邻的元素。如果第一个比第二个大,就交换他们两个。
//对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
//针对所有的元素重复以上的步骤,除了最后一个。
//持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>

</head>
<body>
    <script>

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

      // 遍数
      for (var i = 0; i < arr.length-1 ; i++) {

        var isJiaoHuan = '没有交换';
        // var isJiaoHuan =  true;

        bianshu++;

          // 1 2  3 4 5
          // 次数
          for (var j = 0 ; j < arr.length-1-i; j++) {

              if (arr[j] > arr[j+1]) {

                isJiaoHuan = '交换了';

                // isJiaoHuan =  false;

                  var temp = arr[j];
                  arr[j] = arr[j+1];
                  arr[j+1] = temp;
              }
          }

          if ( isJiaoHuan == '没有交换') {
              // 排好了
              break;
          }

      }

      console.log(bianshu);
    </script>
</body>
</html> 

2. 函数

2.1 为什么要有函数?

重复代码、冗余代码的缺点:

  1. 代码重复,可阅读性差

  2. 不易维护,如果代码逻辑改变了,所有地方的代码都要跟着改变,效率太低。

  • 使用场景 : 只要js出现的地方都有函数

2.2 函数的声明与调用

特点:

1. 函数声明的时候,函数体并不会执行,函数体只有在调用的时候,才会执行;
2. 可以调用多次;

// 声明函数
function sayHi() {
    console.log('萨瓦迪卡');
}

// 调用函数
sayHi();

2.3 函数的参数

  • 形参 ( 形式参数 ) : 在函数声明时, 设置的参数。作用是占位置 。只能在函数内部使用.

  • 实参 ( 实际参数 ) : 在函数调用时,传入的参数。 作用 : 函数调用时,会把实参的值赋值给形参, 这样形参就有了值, 在函数体里,可以直接使用形参!

//带参数的函数声明
function 函数名(形参1, 形参2, 形参...){
  //函数体
}

//带参数的函数调用
函数名(实参1, 实参2, 实参3);

如何确定形参:

在声明函数的时候,碰到不确定的值的时候,就可以定义成形参。

注意:

  • 形参在声明时,值不固定,只有在调用的时候,形参的值才确定,形参的值会跟着函数调用时的实参不一样而不一样。

  • 如何确定形参:在声明函数的时候,碰到不确定的值的时候,就可以定义成形参。

2.4 函数的返回值

 当函数执行完的时候,我们期望函数给我一些反馈(比如计算的结果),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值

//声明一个带返回值的函数
function 函数名(形参1, 形参2, 形参...){
  //函数体
  return 返回值;
}

//可以通过变量来接收这个返回值
var 变量 = 函数名(实参1, 实参2, 实参3);

函数返回值注意事项:

  • return后面的语句不执行。

  • 函数可以没有返回值,函数如果没有return,那么返回结果是undefined。

  • 函数的参数可以有多个,但是返回值只能有1个。

2.5 函数三要素

函数三要素包括:函数名、参数、返回值

注意 : 参数和返回值可以没有,,,但是函数名一定要有;

2.6 函数内部可以调用函数

在函数内部是可以继续调用别的函数的。

 function chiFan() {

      console.log('开始吃饭');
      console.log('吃完了');
    }
    function qiaoDaiMa() {

      console.log('开始敲代码');
      chiFan()
      console.log('代码敲完了');
    }
    qiaoDaiMa()

2.7 函数的断点调试

1) 跳到下个断点, 如果后面没有断点了,那么代码直接执行完 ; 
2) 单步调试 : 下一步   没有断点的话,,,函数就直接跳过   跳过函数 
3) 单步调试 : 进入函数 
4) 单步调试 : 跳出函数
5) 单步调试 : 下一步  不管有没有断点,都会一步一会的走,,,纯碎的下一步
6) 让所有的断点失效
7) 自动根据错误断点,性能不好

2.8 递归函数(了解)

递归函数:自己直接或者间接调用自己的函数;

注意 : 递归函数一定要留有出口,不然就是死循环了(斐波那契数列)

场景 : 少用,,性能也不太好!

2.9 函数也是一种类型

2.9.1 声明函数的两种方式

方式1 : 函数声明:

function 函数名(){
  //函数体
}

方式2 : 函数表达式 ( 匿名函数 )  

var 函数名 = function(){
  //函数体
}

 

2.9.2 函数可以作为参数

通常,我们把作为参数传递的函数叫做回调函数

function fn1(fn) {
  fn();
}
fn1(function(){
   console.log("哈哈"); 
});

2.9.3 函数可以作为返回值

在js高级中,闭包会使用到。

function fn1() {
    return function(){
      console.log("呵呵");
    }
}
fn1()();//调用

 

3. 作用域

作用域:变量起作用的区域

全局作用域 :在script标签内,函数外的区域就是全局作用域,在全局作用内声明的变量叫做全局变量 。全局变量可以在任意地方访问。

函数作用域 :在 函数内的区域 叫做函数作用域,在函数作用域内声明的变量叫做局部变量 ,局部变量只有在当前函数内才能访问到。

全局变量:在函数外,script标签内声明的变量就是全局变量,全局变量在任何地方都能访问的到。

局部变量:在函数中声明的变量,就是局部变量,局部变量只有在当前函数体内能够访问。

隐式全局变量:没有使用var定义的变量也是全局变量,叫做隐式全局变量。(不要使用)

变量的查找规则:

  • 函数内部可以使用函数外部的变量 

  • 有局部变量就用局部变量,没有局部变量就用全局变量

4. 预解析

js执行代码分为两个过程:

  • 预解析过程(变量与函数提升)

  • 代码一行一行执行

// 预解析过程
// 1. 把var声明的变量提升到当前作用域最前面,不会提升赋值 
// 2. 把函数声明 提升到当前作用域的最前面,,
// 3. 如果函数同名 ???  后者会覆盖前者  (帅)
// 4. 如果 var声明的 和 函数声明的同名 ,  函数优先

5. 匿名函数与自执行函数

5.1 匿名函数

匿名函数如何使用:

1). 将匿名函数赋值给一个变量,这样就可以通过变量进行调用
2). 自执行(匿名函数自执行)

匿名函数自执行的作用:防止全局变量污染。

    var a = 10
    var b = 20
    b = a
    (function () {

      console.log(b);

    })();

6. 对象

6.1 对象的基本概念

6.1.1 什么是对象??

现实生活中 : 万物皆对象, 对象是一个具体的事物 , 一个具体的事物就会有 特征 和 行为 ;

JavaScript中: js中的对象就是生活中对象的一个抽象,,,, 没有特征和行为,,取而代之的是有对应的属性和方法 ;

对象 : 是一组无序的键值对的集合

特点 :

1). 声明的变量 = {}  []=> 数组
2). 键值对出现
3). 逗号隔开,, 记住 : 以后再 {} 内一行一行的都是用 , 隔开

6.1.2 为什么要学习对象?

数组:是有序的元素集合 ,数组用于存放一组有序的数据,比如一个班级所有人的名字,一个班级所有人的成绩。

对象:是一组无序的键值对的集合。 对象用于存放一组无序的数据,比如一个人的特征和行为。

6.2 创建对象-1 (2种方式 单创)

单纯的创建一个对象

6.2.1 对象字面量

字面量 : 直接量,,,通过看数值,,直接看出来类型的 ,或者不需要通过创建, 11, '234', true , [] , {}

var p = {};
var p = {
    name : 'zs',
    age:18,
    sayHi:function(){
        console.log(this.name)
    }
}

注意 : this使用在对象的属性的函数里,,其他地方使用没有意义

6.2.2 通过Object构造函数创建

var p =  new Object(); // 创建一个空的对象
var p =  new Object({name :'xx'});

6.2.3 设置对象的属性

// 设置对象的属性的语法
// 对象.属性 = 值
// 1. 如果对象有这个属性,修改这个属性
// 2. 如果对象没有这个属性,添加这个属

// 语法  对象名.属性 = 值
var obj = new Object();
obj.name = 'zs';
obj.age = 18;
obj.gender = '男';

// 添加方法
obj.sayHi = function () {
    console.log('大家好,我是' + obj.name);
}

6.2.4 获取对象的属性

// 获取对象属性的语法:
// 对象.属性:对象的属性
// 1. 如果有这个属性,直接返回属性值
// 2. 如果没有这个属性,返回undefined

// 语法  对象名.属性
console.log(obj.name);
console.log(obj.age);
console.log(obj.gender);

//如果是方法,可以调用
obj.sayHi();

6.3 创建对象-2 (2种方式 批量)

批量创建对象

在实际开发中,经常需要创建多个相同类型的对象,比如游戏中的怪物,班级的学生等。

6.3.1 使用工厂函数创建对象

  //定义一个函数,用于创建学生对象
  //工厂函数:
  function createStudent(name, age, sex) {
    var stu = {};
    stu.name = name;
    stu.age = age;
    stu.sex = sex;
    stu.sayHi = function() {
      console.log("大家好,我是"+this.name);
    }
    return stu;
  }

  var stu1 = createStudent("zs", 18, "男");
  stu1.sayHi();

优点:可以同时创建多个对象

缺点:创建出来的没有具体的类型,都是object类型的

 

6.3.2 查看一个对象的类型

typeof 只能判断基本数据类型的类型
instanceof 判断对象的具体类型
constructor.name 也可以获取到对象的具体类型

关于typeof

  • typeof用于查看基本的数据类型, number string boolean undefined

  • typeof如果查看复杂数据类型,返回的都是object类型。

  • typeof null比较特殊,结果是object

  • typeof 函数的结果是function:因为函数是一等公民

  // 方式1 : typeof
  console.log(typeof num1);
  console.log(typeof num2);
  console.log(typeof num3);
  console.log(typeof num4);
  console.log(typeof num5);
  console.log(typeof num6);
  console.log(typeof num7);
  console.log(typeof num8);


  // typeof 总结 :
  //1. 简单基本类型 : number string boolean undefined 
  //2.                null => object 
  //3. 复杂类型    : object
  //4.                 函数 => fuction 一等公民 

方式2 : instanceof 判断

结构 : 对象 instanceof 构造函数
var arr = [];
var obj = {}
var fn = function () {}
console.log( arr instanceof Array); // true
console.log( obj1 instanceof Object);// true
console.log( fn instanceof Function);// true

 方式3 : constructor.name

// 原型的构造函数    
console.log(arr.constructor.name); //Array
console.log(obj1.constructor.name); //Object
console.log(fn.constructor.name); //Function

6.3.3 自定义构造函数

工厂函数的缺点 就是无法确定对象的具体类型

构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

  //所有创建出来的对象都有:
    //name
    //age
    //hobboy
  function Teacher(name, age) {
    //构造函数内部的this指向的是新创建的那个对象
    this.name = name;
    this.age = age;
  }

  var tea = new Teacher("zs", 18);
  console.log(tea);
  1. 构造函数首字母要大写(推荐做法)。

  2. 构造函数要和new一起使用才有意义。

  3. 构造函数的作用是用于实例化一个对象,即给对象添加属性和方法。

new在执行时会做四件事情 :

new会做4件事情
//1. new会创建一个新的空对象,类型是Teacher
//2. new 会让this指向这个新的对象 
//3. 执行构造函数  目的:给这个新对象加属性和方法
//4. new会返回这个新对象

构造函数的作用(实例化对象): 
  给创建出来的对象增加属性和方法。

7.操作对象的属性

7.1 []语法 ---- 对象名 [ 属性字符串 ] (字符串)

var key = 'name';
console.log ( obj['name'] ) // ok
console.log ( obj[name] ) // X
console.log ( obj[key] ) //ok

二者的区别:当属性名是一个字符串存储在变量中的时候,只能使用关联数组的方式。

应用场景 : 遍历对象

7.2 遍历对象

 通过for..in语法可以遍历一个对象

for (var key in obj) {
    // 键
    console.log(key);
    // 值
    console.log(obj[key]);
}
解析
var obj = {};
for (var i = 0; i < 10; i++) {
		obj[i] = i * 2;
}
for(var key in obj) {
	console.log(key + "==" + obj[key]);
}

7.3 判断一个属性是否是对象的一个属性

结构 :

if (属性名  in  对象) { .. }
var obj = {
	name: 'zs'
}
if ('name' in obj) {
	console.log('是');
}

 

7.4 获取对象里的所有属性

// 结构 :   Object.keys(对象)
Object.keys(obj)

8. 值类型与引用类型

8.1 JS数据类型

简单数据类型:number、string、boolean、undefined、null

复杂数据类型:Array、function, Object

简单数据类型也叫值类型,复杂数据类型也叫引用数据类型,这主要是根据内存存储方式来区分的。

  • 变量在存储简单类型的时候,存的是值本身(值类型)

  • 变量在存储复杂数据类型的时候,存的是引用,也叫地址(类型)

8.2 值类型的存储

变量存储数据的时候,存储的直接就是这个值本身。

练习 :
var num = 11;
var num1 = num;
num = 20;
console.log(num);
console.log(num1);

简单类型进行赋值的时候,赋值的是值本身。

8.3 引用类型的存储

复杂类型: 变量不会存这个对象,对象随机存在内存中,会有一个地址,变量存储的仅仅是这个对象的地址。

练习:
var obj = {
  name:"zs",
  age:18
}

var obj1 = obj;
obj1.name = "ls";
console.log(obj.name);         //ls
console.log(obj1.name);        //ls

把obj存的地址给了obj1  所以obj和obj1都存放了这个对象的地址,

9. 四种创建对象的方式

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>

</head>
<body>
  <script>

    // 两种单独创建的方式
    //1. 字面量 (推荐使用)
    var obj = {};
    var obj = {
      name: 'zs',
      age: 18
    }

    //2. 构造函数 Object (底层)
    var obj = new Object();
    var obj = new Object({
      name: 'zs',
      age: 18
    })

    // 批量创建的两种方式
    //3. 工厂函数
    function createPerson(name, age) {

      //1). 创建一个新对象
      var obj = {};

      //2). 添加属性和方法
      obj.name = name;
      obj.age = age;
      obj.sayHi = function () {
        console.log('哈哈');
      }
      //3). 返回这个新对象
      return obj;
    }

     var zs =  createPerson('zs',18);

     //4. 自定义构造函数
 
     function Person( name ,age) {

       this.name = name;
       this.age = age;
       this.sayHi = function () {
         console.log('哈哈');
         
       }
     }

    var p =   new Person('zs',18);

    console.log( zs.constructor.name);
    console.log( p.constructor.name);
  </script>
</body>

</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值