this关键字和ES6

152 阅读6分钟

this关键字

是js中的关键字,在不同的作用域中,代表的含义是不同的

函数定义好不能确定this含义,通过他的调用方式去分析

全局

this代表window

console.log(this)

普通函数

this代表window

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

自调用函数

this代表window

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

定时器函数

this代表window

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

事件函数

this代表标签

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

对象方法

this代表对象

var obj = {
    name: '张三',
    age: 12,
    eat: function() {
        console.log(this)
    }
}
obj.eat()

箭头函数

this代表上级作用域中的this

var fn = (a => {
    console.log(this);
})
fn()

this含义的改变

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

call方法

调用函数

语法:

函数.call() - 就可以调用函数了

函数.call(参数1) - 就可以调用函数了,并且函数中的this就变成了参数1

函数.call(参数1, 参数2, 参数3, ...) - 就从参数2开始是在给函数传递实参

fn.call()

fn.call(document)

function fn(a, b) {
    console.log(a + b);
    console.log(this);
}
fn.call(document, 1, 2)
精准的检测数据类型

{}.toString.call(数据)

console.log({}.toString.call(new Date()))
// console.log(typeof []);
console.log([1,2,3].toString());
console.log({}.toString.call([1,2,3]));
将伪数组转成数组

伪数组没有数组的方法,不能调用,转成数组

[].slice.call(伪数组)

var arr = [].slice.call(lis)
arr.push(666)
console.log(arr

伪数组本质是对象,获取到元素集合属于伪数组,有length属性,它的键值对中的键的是0 1 2 数字

var lis = document.querySelectorAll('li')
// lis这个标签集合就是伪数组
console.log(typeof lis); // object

var obj = {
    name: '张三',
    age: 12
}
console.log(obj.length);

// 伪数组
var obj = {
    0: '张三',
    1: '李四',
    '2': '王五',
    length: 3
}
console.log(obj);

常见的伪数组:

 元素集合
        document.querySelectorAll()
        document.getElementsByTagName()
        document.getElementsByName()
        document.getElementsByClassName()
    函数中的关键字arguments

apply方法

调用函数

fn.apply()

调用并改变其中的this

fn.apply(document)

function fn(a, b) {
    console.log(a + b);
    console.log(this);
}
fn.call(document, 1, 2)
fn.apply(document, [1, 2])

bind方法

bind语法:

函数.bind() - 返回一个跟原函数一模一样的函数

函数.bind(参数) - 参数是改变后的this

document.onclick = function() {
    // 想让定时器中的this代表document事件源
    // setTimeout(function() {
    //     console.log(this);
    // }, 1000)
    setTimeout(
        (function() {
            console.log(this);
        }).bind(this),
        // // 定时器的函数参数 是 由原本的匿名函数复制出的新函数
        // // 这个新函数中的this被改变了,将他改成 这里的this 了
        1000)
}

ES6

ES6将js从弱类型语言提升到强弱类型语言

提供了很多新的语法,让代码更加简洁,更加严谨

定义变量的关键字

两个关键字的使用语法跟var一样

let

let和var的区别:

1.let定义变量不能预解析

2.let在if或for的大括号中定义,只能在这个大括号中使用了,将大括号当做是一个作用域;循环中执行异步代码或绑定事件,在异步代码中或事件中,可以使用循环的变量

for (let a = 1; a <= 3; a++) {
    setTimeout(function() {
        console.log(a);
    }, a * 1000)
}

3.let不允许重复定义一个变量

const

const和let的区别:

1.const定义变量必须给赋值

2.const变量的值不能改 - 常量

模板字符串

使用反引号定义字符串;可以多行定义一个字符串;在控制台多行显示;在字符串中通过${变量名}直接解析变量,不用拼接

var str = `<img src="${imgPath}" />`
console.log(str);

对象简写

当对象的键和值所使用的变量名同名,就可以简写

var name = '张三'  
var age = 12  
  
var obj = {  
name,  
age  
}  
  
等同于  
var obj = {  
name: name,  
age: age  
}

当对象的键对应的值是匿名函数,就可以简写

var obj = {  
eat() {}  
}  
等同于  
var obj = {  
eat: function() {}  
}

箭头函数

对匿名函数简写

语法:() => {

当只有一个形参的时候,可以省略小括号

var arr = [78, 89, 46, 59, 87] // 小明的考试成绩
// 将所有不及格的成绩找出来
// var brr = arr.filter(function(item) {
//     return item < 60
// })
// console.log(brr);
// 用箭头函数简写
var brr = arr.filter(item => {
    return item < 60
})
console.log(brr);

大括号中只有一行代码的时候,可以省略大括号,如果这行代码中有return,必须省略return

var arr = [78, 89, 46, 59, 87] // 小明的考试成绩
//将所有不及格的成绩找出来
//用箭头函数简写
var brr = arr.filter(item => item < 60)
console.log(brr);

箭头函数本没有this,他里面的this代表箭头函数所在作用域中的this - 上级作用域中的this - 箭头函数上一行代码中的this

document.onclick = function() {
    var fn = () => {
        console.log(this);
    }
    fn()
}

箭头函数中没有arguments这个关键字

形参默认值

在定义的函数的时候,给形参直接赋值,表示在函数内这个参数就算没有实参给他赋值,他也有默认值

function fn(a, b = 2 ) {
    // 形参就相当于函数内提前定义好的变量,默认的值是undefined
    // 默认的值2
    console.log(a, b);
}
fn(1)

解构赋值

将对象或数组中的多个数据 快速的 简洁的 批量的 赋值给多个变量

var {键1, 键2} = 对象

定义了两个变量,变量名分别是键1,键2,值是对象中这两个键对应的值

var obj = {
    name: '张三',
    age: 12,
    sex: '男'
}
var {name, age, sex} = obj // 变量名要跟键的名字保持一致
console.log(name, age, sex);
var {键1: 新的变量名} = 对象

定义了一个变量,变量名是新的变量名,值是键1在对象中对应的值

解构并取别名
var {age: abc} = obj
console.log(abc);
console.log(age); // 取别名后原本的名字就不能用了
var {键1: {键2}} = 对象

定义了变量,变量名是键2,值是对象.键1中 键2对应的值

var obj = {
    name: '张三',
    age: 12,
    sex: '男',
    wife: {
        name: '翠花',
        age: 13,
        sex: '女'
    }
}
var {wife: {name}} = obj
console.log(name);
var [变量名] = 数组

定义变量,值是数组的第一个元素

var a = 1
var b = 2
// 最简短的交换两个变量的值
var [b, a] = [a, b]
console.log(a, b);
var [[变量名]] = 数组

定义变量,值是数组中第一个数组中的第一个值

var arr = [1,2,[5,6]]
var [_, _, [_, b]] = arr
console.log(b);

展开合并运算符: ...数组名

当他作为实参的时候,是将一个数组,展开成多个值

//快速求数组中的最大值
var arr = [1,5,9,7,6,4,3,2,8]
console.log( Math.max(...arr) );

将一个对象展开成多个键值对

var lw = {
    name: '隔壁老王',
    sex: '男',
    age: 60
}

var zs = {
    ...lw, // 快速的将lw展开成多个键值对
    /*
    等同于
        name: '隔壁老王',
        sex: '男',
        age: 60
    */
    wife: {
        name: '翠花',
        age: 13,
        sex: '女'
    }
}

当他当做形参的时候,是将多个实参收集成一个数组

function add(...arr) { // 实参数量不固定,将所有实参收集在一个arr数组中
    console.log(arr);
    console.log( {}.toString.call(arr) );
}

add(1, 2)
add(1, 2, 3)
add(1, 2, 3, 4)
add(1, 2, 3, 4, 5, 6)