JavaScript——this关键字和ES6

本文详细介绍了JavaScript中的this关键字在不同场景下的指向,以及如何通过call、apply和bind方法来改变this的指向。此外,还探讨了ES6的新特性,包括let和const变量声明、箭头函数、函数默认值、模板字符串、解构赋值、展开运算符、对象简写方式、Map和Set数据结构及其常用操作。
摘要由CSDN通过智能技术生成
一、this关键字
  1. this的关键含义

(1)全局的this:指向window对象

console.log(this)

(2)普通函数中的this:指向window对象

function fn() {
    console.log(this)
}
fn()

(3)自调用函数中的this:指向window对象

(function() {
    console.log(this)
})()

(4)定时器中的this:指向window对象

setTimeout(function() {
    console.log(this)
}, 1000)

(5)事件函数中的this:指向.前面的事件源

<button id="btn">按钮</button>
btn.onclick = function() {
    console.log(this)
} 
//this指向:<button id="btn">按钮</button>

(6)对象方法中的this:指向.前面的调用对象

var obj = {
    name: '张三',
    age: 12,
    eat: function () {
        console.log(this)  //指向obj对象
    }
}
obj.eat()   
  1. this关键含义的修改

js提供了3个函数来强行修改this关键字的含义:

  • call方法:调用函数以及改变函数中的this

1.函数名.call(要改变的this指向的对象,实参1,实参2...)
function fn(a, b) {
    var c = a + b
    console.log(c)
    console.log(this)
}
fn(1, 2) // 3 window
fn.call(document, 2, 3) // document 5
fn.call(null, 5, 6) // window 11
//第一个参数为null,则将函数中的this指向window

2.数组方法.call(伪数组):通常用于将伪数组转成数组,方便调用数组方法处理元素
var divs = document.querySelectorAll('div')
var arr = []
var newDivs = arr.slice.call(divs, 0)
console.log(newDivs);

3.对象.toString.call(数据):检测数据为对象时的精准类型
var obj = {}
console.log(obj.toString.call(123));
console.log(obj.toString.call('abc'));
console.log(obj.toString.call(true));
console.log(obj.toString.call(undefined));
console.log(obj.toString.call(null));
console.log(obj.toString.call([]));
console.log(obj.toString.call({}));
console.log(obj.toString.call(function(){}));
console.log(obj.toString.call(/^abc$/));
console.log(obj.toString.call(new Date()));
  • apply方法:apply和call的作用是相同的,唯一不同的地方,在于传递实参

函数名.apply(要改变的this指向的对象,[实参1,实参2...])
function fn(a, b) {
    var c = a + b
    console.log(c)
    console.log(this)
}

fn(1, 2) // 3 window
fn.apply(document, [2, 3]) // document 5

注意:以上两个方法,在修改了函数中的this关键字之后,并直接调用该函数;

  • bind方法:复制函数,并改变新函数中的this。

函数名.bind(要改变的this指向的对象);  //返回新函数
var obj = {
    name: '张三',
    eat: function() {
        console.log(this);
    }
}
var fn = obj.eat.bind()  
fn() // window

// 将定时器中的this改为document
document.onclick = function() {
    setTimeout((function() {
        console.log(this)
    }).bind(this), 1000)
}

注意:使用bind()方法改变函数中this关键字指向之后,会把修好的函数引用地址给返回,因此需要再次调用返回之后的函数引用地址;

  • call、apply和bind之间的区别:

call和apply的区别:两个函数都是改变函数执行上下文的,但是传的参数不同

bind和其他两个差别在:传参与call相同,但是bind会返回一个新的函数

二、ES6
  1. 变量

es6新增了两个类似于var的关键字来定义变量,分别是let和const。

  • let关键字:

  • Let和var的区别:

  • let不允许重复定义

  • let定义的变量没有预解析

  • let定义的变量会自己创建一个块级作用域,将自己的作用域限制在大括号中。(let自带块级作用域,全局定义的变量也不在window中,if和for中的let变量不能在大括号外面访问了)

  • const关键字:

  • const关键字也是用来定义变量的,具备let的所有特性;

  • const定义的变量的值不能修改;

  • const声明的时候必须赋值

  1. 箭头函数
//箭头函数是对匿名函数的简写
let fn = () => {
    console.log(111)
}
//带参数的写法
let fn = (a,b) => {
    console.log(a+b)
}
//当只有一个形参的时候,可以省略小括号,当大括号中只有一行代码的时候可以省略大括号
let fn = a => console.log(a)
//这行代码中如果有return就必须省略return
let fn = a => a+1
  • 箭头函数定义好以后就已经知道箭头函数中this的含义了,且不可改

  • 箭头函数中没有this指向,该函数中的this指向跟它的上下文有关,也就是说函数的上下文中的this指向哪里,那么箭头函数中的this也就指向哪里;箭头函数中的this和调用无关,主要是和在哪里创建有关;

  • 箭头函数中没有argument对象

  1. 函数默认值

es6的函数中可以定义默认值:

function add(a,b=2){
    return a + b;
}
console.log(add(5));  //7
//箭头函数改写为
let add=(a,b=2)=>a+b;
console.log(add(5))   //7
  1. 模板字符串
var s=`字符`   // 使用反引号
  • 模板字符串和普通字符串区别:

(1)前者中的内容可以换行,保持字符串中的换行和空格;后者不行

(2)前者里面可以直接书写变量,后者不行

模板字符串中可以识别变量,使用美元符大括号:${变量}

  1. 解构赋值

作用:可以快速的从数组或对象中提取元素

[ ]:解构数组

let arr = [1,2,3];
let [num1] = arr;   //从数组中拿出第一个元素赋值给num1变量
let [num1,num2,num3] = arr;   //解构多个元素
//多维数组解构
let arr = [1,2,3,[4,5,6]];
let [a,b,c,[aa,bb]] = arr;
console.log(aa,bb); // 4 5
//利用解构给两个数交换位置
let num1=10
let num2=20
let [num2,num1]=[num1,num2]
console.log(num1,num2)

{ }:解构对象

let obj = {
    name:"张三",
    age:12,
    sex:"男",
    wife:{
        name:"翠花",
        age:11,
    }
}
let {name} = obj;  
let {name:n} = obj;   //可以有别名
console.log(n)        //有别名则输出name无效
let {name,age,sex}=obj;          //解构多个变量
let {wife:{name:wname}} = obj;  //多级解构

注意:在解构对象时,{ }中变量名,需要跟对象中的键名同名

  1. 展开运算符
// 可以将数组中的元素展开
let arr = [1,2,3];
console.log(...arr)
// 可以将多个变量赋值给多个形参
let arr = [1,2,3];
function fn(a,b,c){
    console.log(a,b,c); // 1 2 3
}
fn(...arr);
// 对象可以在对象中展开,进行合并;但是不能直接展开对象输出
const obj = {
    name:"Jack",
    age:20,
    sex:"男",
}
const obj1 = {
    ...obj,
    wife:{
        name:"Rose",
        age:18
    }
}
console.log(obj1);
  1. 合并运算符
//将多个实参合并为一个数组
function fn(...arr){
    console.log(arr);
}
fn(1,2,3); // [1,2,3]
//箭头函数可以改为
let fn=(...arr)=>console.log(arr)
fn(1,2,3)
  1. 对象的简写方式

当前对象中的键名跟键值的变量名相同时,可以只写一个键名;

对象中的方法,可以直接简写成方法名(){ }

var name1='丽丽'
var age1=18
var o1={
    name1,
    age1,
    fn1:function(){
        console.log("hello")
    },
    fn2(){
        console.log("world")
    }
}
  1. Map构造函数
  • 里面存储在的数据类似于对象,只不过它的键名可以是任意数据类型

var m=new Map()
//()参数是二维数组
var obj = {
    sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
console.log(m);
// map的结构使用[],其中的数据也必须是[],在里面的[]中第一个为键,第二个为值,如果只有键没有值,默认的值为undefined。
  • Map对象中常用的属性和方法:

map.size:获取元素个数,返回数字。

map.get(key):根据键名获取指定的键值;如果获取一个map中不存在的键,返回undefined。

map.set(key,value):给map对象设置键值对;如果map中已经有了当前指定的键,后面的值会覆盖前面的值。

map.delete(key):删除指定的键值;返回boolean,代表是否删除成功;删除map中不存在的键,返回false。

map.keys():获取所有键的集合。

map.values():获取所有值的集合。

map.clear():清空所有键值对。

map.has(key):查找当前键名是否在map对象中存在,返回boolean。

map.forEach((value,key)=>{ }):遍历map对象中所有元素。

  1. Set构造函数
  • 存储的数据结构跟数组非常相似,里面的元素是唯一不重复的

var s1=new Set(数组或伪数组)
//数组去重
var s = new Set([1,1,2,2,2,3,4,2,1])
console.log(s);
  • Set对象中常用的方法和属性:

set.size:获取当前set对象中元素的个数

set.add():给set对象添加元素;添加元素时,会检查set对象中是否存在该元素,如果存在,则不添加;如果不存在,则添加;

set.delete():删除set对象中指定的元素

set.clear():清空set对象中所以元素

set.has():查找当前元素是否在set对象中存在,返回boolean

set.forEach(item=>{ }):遍历set对象中所有元素

注意:set对象中的元素不能通过下标直接获取

  1. for、for...in、forEach、for...of之间的区别
  • for循环

可以遍历数组;但是不可以遍历对象;可以使用break,continue语句跳出循环;

  • forEach

可以遍历数组、Set集合、Map集合;但是不可以遍历对象、字符串;也不可以使用break, continue, return控制循环;

  • for in

可以遍历对象、数组(遍历数组的时候会将数组的下标作为键)、字符串;也不可以使用break, continue, return控制循环;

  • for of

可以遍历数组、字符串、Set集合、Map集合;但是不可以遍历对象;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值