js笔记(二)数组、对象、this

大标题小节
一、数组1. 数组的创建、赋值、分类
2. 数组的简单操作(根据索引增、查、改)
3. 声明式和构造函数创建的数组的区别
4.数组的方法:push()unshift()splice()pop()shift()slice()
sort()reserve()join()toString()contat()
二、对象1. 对象的书写规则
2. 创建对象
3. 操作属性值
4. 操作属性
5. 对象的遍历 for-in
6. 深浅拷贝
7. 基础类型和引用类型
三、this1. 在 js 中,全局的变量和函数,全部属于 window,this 指向 window
2. 在方法中,this 表示该方法所属的对象。
3. 在函数中,this 会指向 window,但在严格模式下,函数中的 this 会指向 undefined
4. 在事件中,this 表示接收事件的元素,即接收事件的 HTML 元素。
总结

一、数组

注意:不要在循环中使用 return,否则会终止循环。如果一定要使用,将原本要 return 的最终结果,存到数组中,再将这个数组 return 出来。

1. 数组的创建、赋值、分类:

(1)创建:
① 声明式创建: var arr = [];
② 构造函数创建: var arr2 = new Array();

(2)赋值:
var arr = [4,5,6,7];
var arr2 = new Array(7,8,9,0,1);

(3)分类:
① 伪数组:例如 arguments
② 数组: 整数数组、字符串数组、json对象数组、二维数组;


2. 数组的简单操作(根据索引增、查、改):

(1)增:

var arr = [];
arr = [4,'a',true,undefined,NaN,null,{},[],function(){console.log("hello")}];

console.log(arr[9]);//undefined  声明了arr,但是arr下标为9的位置未赋值
arr[9] = "world";
console.log(arr);//(10) [4, "a", true, undefined, NaN, null, {…}, Array(0), ƒ, "world"]
  • 注意:打印的时候,浏览器显示的是 (2) [empty,0],实际上 arr2[0] 的值是 undefined,而不是 empty
    var arr2 = [];
    arr2[1] = 4;
    console.log(arr2);  //(2) [empty,0] 
    console.log(arr2[0]); //undefined
    

(2)查:

var arr = [4,'a',true,undefined,NaN,null,{},[],function(){console.log("hello")}];

console.log(arr[1]);//a

arr[8]();//hello

for(var i =0;i<arr.length;i++){
	console.log(arr[i]);
}

(3)改:

var arr = [4,'a',true,undefined,NaN,null,{},[],function(){console.log("hello")}];
arr[2] = "hello";
console.log(arr[2]); //hello

3. 声明式和构造函数创建的数组的区别:

(1)使用声明式:

var arr1 = [];  // 创建空数组
var arr2 = [ 20 ];   // 长度为1,数据是20
var arr3 = [ "2","6","9" ]; // 创建带有三个字符串的数组
console.log(arr2);  //[20]
console.log(arr3);  //(3) ["2", "6", "9"]

(2)使用 Array 构造函数

var arr1 = new Array( );  // 创建空数组
var arr2 = new Array( 20 );   // 长度是 20 的空数组
var arr3 = new Array( "2","6","9" ); // 创建带有三个字符串的数组
console.log(arr2);  //(20) [empty × 20]
console.log(arr3);  //(3) ["2", "6", "9"]

4. 数组的方法:

以下所列方法中:

  • 会改变原数组的方法:push()unshift()splice()pop()shift()splice()sort()reverse()
  • 返回新数组,不影响原数组的方法:slice(n,m)join()toString()concat()

(1)增:push()unshift()splice()

  • push(),给数组的最后一位增加;

    var arr = [4,5,6,7];
    
    arr.push("hello");
    console.log(arr);//(5) [4, 5, 6, 7, "hello"]
    
  • unshift(),给数组的第一位增加;

    var arr = [4,5,6,7];
    
    arr.unshift("hello");
    console.log(arr);//(5) ["hello", 4, 5, 6, 7]
    
  • splice(指定位置(从0开始,指定位置包括自身), 删除个数, 新增内容),给指定索引的位置增加;

    var arr = [4,5,6,7];
    
    arr.splice(1,2,"world");
    console.log(arr);//(3) [4, "world", 7]
    arr.splice(1,0,2);
    console.log(arr);//(4) [4, 2, "world", 7]
    arr.splice(1,1,"hello"); //相当于替换
    console.log(arr);//(4) [4, “hello”, "world", 7]
    

(2)删: pop()shift()splice()

  • pop(),删除数组的最后一个;

    var arr = [4,5,6,7,8,9];
    
    arr.pop();
    console.log(arr);//(5) [4, 5, 6, 7, 8]
    
  • shift(),删除数组的第一个;

    var arr = [4,5,6,7,8,9];
    
    arr.shift();
    console.log(arr);//(5) [5, 6, 7, 8, 9]
    
  • splice(指定位置(从0开始,指定位置包括自身),删除个数)

    var arr = [4,5,6,7,8,9];
    
    arr.splice(1,1);
    console.log(arr);//(5) [4, 5, 7, 8, 9]
    

(3)截取: slice(n,m)(截取数组的第 n 位到第 m 位的前一位,含前不含后。返回新数组,不操作/影响原数组)

var arr = [4,5,6,7,8,9];
console.log(arr);//(6) [4,5,6,7,8,9]

arr.slice(1,3);
console.log(arr);  //(6) [4,5,6,7,8,9] 
//当使用方法时,返回原数组,发现没有变化时,可能是这个方法把处理结果放在返回值中。
//就像在 slice() 方法中有个 return。
console.log(arr.slice(1,3));  //(2) [5,6]
var newArr = arr.slice(1,3);
console.log( newArr );        //(2) [5,6]

(4)排序:sort()reverse()

  • sort(),默认按字符升序排列;
    var arr = [4,6,5,3,8];
    arr.sort();
    console.log(arr);//(5) [3, 4, 5, 6, 8]
    
    var arr2 = [2,101,6,58,3]
    arr2.sort();
    console.log(arr2);//(5) [101, 2, 3, 58, 6]
    
    var arr3 = ["Banana", "Orange", "Apple", "Mango"]
    arr3.sort();
    console.log(arr3);  //(4) ["Apple", "Banana", "Mango", "Orange"]
    
    解决 sort() 按位排序的方法:
    //升序:
    var arr2 = [2,101,6,58,3]
    arr2.sort(function(a,b){return a-b;})
    console.log(arr2);  //(5) [2, 3, 6, 58, 101]
    
    //降序:
    arr2.sort(function(a,b){return b-a;})
    console.log(arr2);  //(5) [101, 58, 6, 3, 2]
    
  • reverse(),反向排序,将数组中的元素颠倒顺序,返回逆序后的数组。
    var arr = ["Banana", "Orange", "Apple", "Mango"]
      arr.reverse();
      console.log(arr); //(4) ["Mango", "Apple", "Orange", "Banana"]
    

(5)数组转为字符:join()toString()

  • join(),将数组转为字符,参数会将逗号替换掉,返回一个新数组;
    var arr = [2,6,8,9];
    console.log(arr.join());    //2,6,8,9
    console.log(arr.join(''));  //2689
    console.log(arr.join('-')); //2-6-8-9
    
  • toString(),也可以将数组转为字符,返回一个新数组;
    var arr = [2,6,8,9];
    console.log(arr.toString());  //2,6,8,9
    

(6)合并两个或多个数组:concat(),返回新数组,不影响原数组。

var a = [2,6,8,9];
var b = ["hello", "world", "I"];
var c = [4, 7];
var result = a.concat(b, c);
console.log(result);  //(9) [2, 6, 8, 9, "hello", "world", "I", 4, 7]

5. 数组的遍历(获取数组中的每个元素):for()

(1)定义一个 30 项的数组,数组每一项要求是 1-10 的随机数,每间隔 5 个数字,求出前 5 个数的平均值。

var arr = new Array(30);
var newArr = [];
var aveArr = [];
for(var i=0; i<30; i++){
  arr[i] = Math.round(Math.random()*9+1)
}
for(var i=0; i<30; i=i+5){
  newArr.push( arr.slice(i, i+5) );
}
console.log(newArr)
for(var i=0; i<newArr.length; i++){
  aveArr.push( ave(newArr[i]) )
}
console.log(aveArr)

//求数组每个值之和的平均值
function ave(arr){
  var sum=0;
  for(var i=0; i<arr.length; i++){
    sum += arr[i];
  }
  return sum/arr.length;
}

(2)数组去重(利用 对象 添加属性得到undefined)

通过obj.A,就可以给对象添加一个值为 undefined 的属性A。

  1. 定义一个空对象 obj,遍历数组;
    判断数组中的第一个值在obj中是否存在,如果不存在,就将这个值作为对象的键,给它赋值为1,如果存在,就把它的值+1。判断第二个值在obj中是否存在…一次类推.
var arr = ['a','b','a','a','b','a'];
var obj = {};
for(var i=0; i<arr.length; i++){
	if( obj[arr[i]] ){  
		obj[arr[i]]++;
	} else { 
		obj[arr[i]] = 1;
	}
}
console.log(obj);//{a:4, b:2},得到的是a和b在数组中的重复个数
var newArr = [];
for(var key in obj){
	newArr.push(key);
}
console.log(newArr);  //[a,b]

6. 冒泡排序比较排序

(1)冒泡排序:依次对数组中相邻数组进行比较。如果第一个比第二个大,就交换他们两个。
在这里插入图片描述

var arr = [12,9,6,8,3,4];
for(j = 0; j<arr.length-1; j++){
	for(var i = 0; i<arr.length-1-j; i++){
		if(arr[i] > arr[i+1]){
			var temp  = arr[i];
			arr[i] = arr[i+1];
			arr[i+1] = temp;		
		}
	}
}

(2)比较排序:将第一位依次与后面的元素相比较,得到最小值,与第一位交换,再用第二位依次与后面的元素相比较,得到最小值,再与第二位交换…;
在这里插入图片描述

var arr = [3,1,2,4,6,9];
for(var i = 0;i<arr.length; i++){
  var min = arr[i];//假设为最小值
  var minIndex = i;//最小值的index

  for(var j = i+1; j<arr.length; j++){ //i与后面所有的值做比较
    if(min > arr[j]){
      min = arr[j];
      minIndex = j;
    }
  }

  arr[minIndex] = arr[i];
  arr[i] = min
}
console.log(arr);


二、对象

  • 存储数据的载体称为变量,在对象中称为属性;
  • 功能实现的载体称为函数,在对象中称为方法;
  • 当只操作对象进行编程的时候,称为“面向对象编程”。
  1. 对象: 其实就是一种类型,即 引用类型。对象的值就是引用类型的实例。
    在 ECMAScript 中引用类型是一种数据结构,用于将数据和功能组织在一起,它也常被称为“类”。
  2. 对象的组成:属性(键、key) 和 属性值(值、value) 组成;
  3. 作用:
    (1)储存数据;(2)用来编程;
1. 书写规则:

(1)属性可以直接写,类似于变量名;
(2)属性值可以是任意数据;
(3)键和值之间用 “:” 连接;
(4)没对属性之间用“,”隔开。

  • 对象的值可以是数字、字符、布尔值、undefined、null、对象、数组、函数(函数在对象中叫做 “方法”
    var obj = {
      num: 1,
      str: "hello",
      bool: true,
      und: undefined,
      nul: null,
      obj: {},
      arr: [],
      fn: function(){
      	console.log(1);
      }
    }
    

2. 创建对象

所有对象都不相等,但是对象身上的属性可以相等;
(1)字面量方式创建:var obj = {};
(2)构造函数的方式创建:var obj = new Object();

  • 构造函数new,用来执行(构造)函数;

  • 构造函数的特点
    (1)所有通过 new 调用的函数,不管有没有返回值,都会得到一个函数的同名对象,每次 new 得到的不是同一个;

    (2)构造函数只会产生对象,构造函数是用来构造对象的函数(不能用 ypeof 来检查数据类型。);

    function fn(){
    	console.log(1)
    }
    var a = new fn();
    var b = new fn();
    console.log(a);//fn {}
    console.log(b);//fn {}
    console.log(a == b);//false
    
  • 内部用this 来构造属性和方法

    function Person()
    {
         this.name="hxl";
         this.age=18;
         this.sayHi=function()
             {
              alert("Hi")
             }
     } 
    var a = new Person();
    console.log(a);//Person {name: "hxl", age: 18, sayHi: ƒ}
    

3. 操作属性值

(1)获取
① 通过 . 拿到对象中的值;也可以使用 obj["属性名"],注意要加双引号
当 i 是变量时,我们不能用 obj.i 去访问,而要用 obj[i]
③ 获取一个对象中不存在的属性时,它的属性值为 undefined

var obj = {
	"a":1,
	"b":"hello",
	"c":true,
	"d":function(){
		console.log("haha");
	},
	"e":function(){
		return {
			fn:function(){console.log(111);}
		}
	}
};
//两种获取方式:
console.log(obj.a);//1
console.log(obj["a"]);//1 此处若不加双引号,意味着 a 是一个变量
console.log(obj["" + "a"]);//1  用 [] 的方式获取,里面还可以对变量进行拼接

//获取和调用对象中的函数
console.log(obj.d); //f (){console.log("haha");}
console.log(obj.d()); //haha

console.log(obj.e);//f (){return{ fn:function(){console.log(111);} }}
console.log(obj.e());//{fn:f}
console.log(obj.e().fn);//f (){cosnole.log(111);}
console.log(obj.e().fn());//111

//获取对象中不存在的属性名
console.log(obj.x); //undefined

(2)改值: obj.c = false;


4. 操作属性

(1)赋值:
① 直接赋值:var obj = {"a":1,"b":2};

② 变量赋值:

var obj = {};
obj.a = 20;
console.log(obj)//{a:20}
obj.fn = function(){
	console.log(1);
}
console.log(obj);//{a:20,fn:f}

(2)删除对象中的某个属性:delete 对象.属性名;

var obj = {
  name: "admin",
  age: 18,
  sex: "保密",
  height: "180cm",
  weight: "70KG",
  like: ["read","sport","wirte"]
}
delete obj.like;
console.log(obj);  //{name: "admin", age: 18, sex: "保密", height: "180cm", weight: "70KG"}

5. 对象的遍历 for-in

(1)for-in 用于非数组对象的遍历,常用于对象的遍历
因为 obj.length 得到的是 undefined,所以普通的 for() 对 对象 没有用

枚举: for-in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作,这种循环也称“枚举”。

var obj = {
			name:"hxl",
			age:20,
			show:function(){
				console.log("hello")
			},
			skill:"编程"
};
for(var i in obj){
	console.log(i);//name age show skill
	console.log(obj.i);//undefined undefined undefined undefined
	//注意:
	//原因: i 不是 obj 身上的属性,这里的 i 只是一个变量。
	//当 i 是变量时,我们不能用 obj.i 去访问,而要用 obj[i]
	console.log(obj[i]);//hxl 20 f (){console.log("hello")} 编程
}

(2)Object :适用于 所有可枚举属性的 对象(包括字符串)。

Object.keys():返回值是一个由原对象的 key/键/属性名 组成的新数组

  • 传入普通数组,返回 索引
    var arr = ['a', 'b', 'c'];
    console.log(Object.keys(arr)); // ['0', '1', '2']
    
    //传入对象,返回 键/属性名
    var obj = { a: 'alive', b: 'bike', c: 'color' };
    console.log( Object.keys(obj) ); // ['a', 'b', 'c']
    
  • 传入对象,返回 键/属性名
    var obj = { a: 'alive', b: 'bike', c: 'color' };
    console.log( Object.keys(obj) ); // ['a', 'b', 'c']
    

Object.values():返回值是一个由原对象的 value/值/属性值 组成的新数组

const obj = { id:1, name:'zhangsan', age:18 }
console.log(Object.values(obj)); // ["1", "zhangsan", "18"]
  • 补充: Object.assign({}, 对象1, 对象2, 对象3) 合并两个或多个对象,返回一个新对象,不修改原对象。
    var obj1 = {a:1, b:2};
    var obj2 = {c:3, d:4};
    console.log(Object.assign({}, obj1, obj2); // {a:1, b:2, c:3, d:4}
    

6. 深浅拷贝

(1)值传递: 在拷贝的时候,拷贝的是值;
在这里插入图片描述

  var a = 10;
  var b = a;
  console.log(a, b); //10 10
  
  b = 20;
  console.log(a, b); //10 20

(2)引用传递: 在拷贝的时候,拷贝的是指针(内存地址);
在这里插入图片描述

var obj1 = {"name":"admin"};
var obj2 = obj1;
console.log(obj1, obj2);//{name: "admin"}  {name: "admin"}
 
obj2.name = "hxl";
console.log(obj1, obj2);//{name: "hxl"}  {name: "hxl"}

(3)对象的深浅拷贝

  • 浅拷贝(直接复制,数组和对象): 只拷贝内存地址,当修改拷贝之后的数据时,会影响原数据;引用传递
    对象本身是引用传递,浅拷贝。
  • 深拷贝: 不拷贝内存地址,只拷贝值,当修改拷贝之后的数据时,不会影响原数据。值传递

(4)浅拷贝 转换为 深拷贝:(常使用深拷贝)
① 整个赋值:

 var obj1 = {"name":"hxl"};
 var obj2 = obj1;
 obj2 = {"name":"zjx"};
 console.log(obj1);//{name: "hxl"}
 console.log(obj2);//{name: "zjx"}

//或者 相比上面的方法,建议
 var obj1 = {"name":"hxl"};
 var obj2 = {}; //给自己一个存储空间
 obj2.name = obj1.name;
 obj2.name = "root";
 console.log(obj1);  //{name: "hxl"}
 console.log(obj2);  //{name: "root"}

② 当对象有多个属性和属性值时:

var obj1 = {name:"admin",age:18};
var obj2 = {};
for(var i in obj1){
	obj2[i] = obj1[i];
}
obj2.name = "root";
console.log(obj1);  //{name: "admin", age: 18}
console.log(obj2);  //{name: "root", age: 18}

③ 当对象有多个属性和属性值时,属性值又是对象:

使用JSON.stringify将数据转换成字符,再用JSON.parse转换成对象。

this.labelListData = JSON.parse(JSON.stringify(this.editLabelList));

7. 基础类型和引用类型

基础类型都是值传递,引用类型都是引用传递。

(1)值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(ES6 引入了一种新的原始数据类型,表示独一无二的值)。

(2)引用数据类型:对象(Object)、数组(Array)、函数(Function)。



三、this

  1. this 是一个指针、变量、对象。表示当前函数所在的执行上下文空间(即当前的执行环境);
  2. 面向对象语言中 this 表示当前对象的一个引用,但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
  • this 指向问题:
    (1)在 js 中,全局的变量和函数,全部属于 window,this 指向 window
    (2)在方法中,this 表示该方法所属的对象。
    (3)在函数中,this 会指向 window,但在严格模式下,函数中的 this 会指向 undefined
    (4)在事件中,this 表示接收事件的元素,即接收事件的 HTML 元素。
1. 在 js 中,全局的变量和函数,全部属于 window。
var a = this;
console.log(a, window);

在这里插入图片描述


2. 在方法中,this 表示该方法所属的对象。

在对象方法中, this 指向调用它所在方法的对象。

//this 表示 person 对象。fullName方法所属的对象就是 person,this.firstName相当于person.firstName
var person = {
  firstName: "John",
  lastName : "Doe",
  id : 5566,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};
console.log( person.fullName() );  //John Doe

3. 在函数中:在函数中会生成一个区域,也叫做作用域;除此之外,在函数中还存在另外一个东西——this

(1) 在函数中,函数的所属者默认绑定到 this 上,在浏览器中,window 就是该全局对象。回调函数中的 this 也指向window。

  • 普通函数

    function myFunction() {
      return this;
    }
    console.log(myFunction())
    

    在这里插入图片描述

  • 回调函数:回调函数就是把一个函数作为参数 传递给另一个函数。

    var obj = {
      name: "admin",
      show: function (fn) {  
        console.log(this);  //指向obj
        fn();
      }
    }
    obj.show( function(){  //obj.show中的这个以函数为参数的函数就是“回调函数”
      console.log(this);  //指向window
    })
    

    其实拆分出来,相当于:

    var obj = {
    name: "admin",
    show: function () {  
      console.log(this);  //指向obj
      function fn(){
        conosle.log(this); //指向fn,fn属于window
      }
      fn(); //window.fn();
    }
    }
    obj.show();
    

(2)严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。

function myFunction() {
  "user strict";
  return this;
}
console.log(myFunction());  //undefined

4. 在事件中,this 表示接收事件的元素。

在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。

<button onclick="this.style.display='none'">
	点我后我就消失了
</button>

总结:
  1. 观察一个函数或变量,看前面有没有对象,如果有对象,那么就属于这个对象,如果没有就属于window。

  2. this 指向的必须是一个对象,如果不是对象,会强行当成 一个对象;

  3. call() 和 apply() 方法可以将 this 引用到任何对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值