this指向详解
-
this出现在全局范围调用函数时,永远指向window (this所在的function没有被明确的对象调用时,this指向window)
var Car = function() { console.log(this); // window console.log(this.Car==window.Car,Car==window.Car); // true true } Car();
<script> 1. this代表所在function被哪一个对象调用了,那么这个this就代表这个对象。 2. 如果没有明确的调用对象,则代表window function fn(){ alert(this); } fn(); window //没有明确对象,所以代表 document.onclick = fn; document var obj = {fn: fn} obj.fn(); obj 'use strict'; a = 3; alert(a); function fn(){ 'use strict'; alert(this); undefined } fn(); </script>
-
this出现在函数作用域严格模式中,永远不会指向window
函数中使用ES5的严格模式‘use strict',this为undefined
function car() {
'use strict'
console.log(this); // undefined
}
car();
-
当某个函数为对象的一个属性时,在这个函数内部this指向这个对象
var car = { name:'丰田', run() { console.log(this); // {name: "丰田", run: ƒ} } }
-
this出现在构造函数中,指向构造函数新创建的对象
var Car = function(name) { = name; console.log(this); // Car {name: "亚洲龙"} // Car {name: "汉兰达"} } var myCar_1 = new Car('亚洲龙'); var myCar_2 = new Car('汉兰达');
-
当一个元素被绑定事件处理函数时,this指向被点击的这个元素
var btn = document.querySelector('button'); btn.onclick = function() { console.log(this); // <button>this</button> }
-
this出现在箭头函数中时,this和父级作用域的this指向相同
const obj = { Car() { setTimeout(function() { setTimeout(function() { console.log(this); // window }) setTimeout(()=>{ console.log(this); // window }) }) setTimeout(() => { setTimeout(function() { console.log(this); // window }) setTimeout(()=>{ console.log(this); // obj }) }) } } obj.Car();
强行改变 this 指向
修改上下文中的this指向方法 (函数的方法,改变的是函数内部的this指向)
-
call(对象,参数1,参数2,……) :返回对象后,这个函数立即运行
-
apply(对象,数组或arguments) : 返回对象后,这个函数立即运行
-
bind(对象,参数1,参数2,……) : 返回函数
<script>
var div = document.querySelector('#box');
var inp = document.querySelector('#txt');
document.onclick = function(){
alert(this); //document
setTimeout(function(){
alert(this); //window,想让this指向document
}.bind(this), 3000); //document
}
function fn(){
alert(this);
}
fn.call(div); // div
fn.apply(document); //document
fn.bind(inp)(); // input
</script>
ES6相关内容
let / const
let : 用于声明变量
-
必须先声明,后使用。(变量不再做提升了)
-
let声明的全局变量不是window对象的属性。
-
在同一个作用域中,let不能重复声明同一个变量。
-
let声明会产生块级作用域,for循环有两个作用域,for本身是一个作用域,for循环体又是子级作用域。
const : 用于声明常量
-
常量一旦声明,不允许修改。
-
基本类型的数据,值不允许修改。
-
复合类型的数据,引用地址不允许修改。
let
和 const
的区别
-
let
声明的变量的值可以改变,const
声明的变量的值不可以改变 -
let
声明的时候可以不赋值,const
声明的时候必须赋值
箭头函数
-
箭头函数是 ES6 里面一个简写函数的语法方式
-
重点: 箭头函数只能简写函数表达式,不能简写声明式函数
function fn() {} // 不能简写
const fun = function () {} // 可以简写
const obj = {
fn: function () {} // 可以简写
}
语法:
(函数的行参) => { 函数体内要执行的代码 }
const fn = function (a, b) {
console.log(a)
console.log(b)
}
// 可以使用箭头函数写成
const fun = (a, b) => {
console.log(a)
console.log(b)
}
-
箭头函数不利于阅读
-
箭头函数中没有this指向,指向上下文中的this.
-
箭头函数不能实现构造函数
-
箭头函数不能new
-
建议在回调函数中使用箭头函数。
-
箭头函数内部没有
arguments
这个参数集合 -
函数的行参只有一个的时候可以不写
()
其余情况必须写 -
函数体只有一行代码的时候,可以不写
{}
,并且会自动 return
-
回调函数:当一个函数作为另一个函数的参数时,这个函数就是回调函数。
函数参数默认值
-
我们在定义函数的时候,有的时候需要一个默认值出现
-
就是当我不传递参数的时候,使用默认值,传递参数了就使用传递的参数
function fn(a) { a = a || 10 console.log(a) } fn() // 不传递参数的时候,函数内部的 a 就是 10 fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
-
在 ES6 中我们可以直接把默认值写在函数的行参位置
function fn(a = 10) { console.log(a) } fn() // 不传递参数的时候,函数内部的 a 就是 10 fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
-
这个默认值的方式箭头函数也可以使用
const fn = (a = 10) => { console.log(a) } fn() // 不传递参数的时候,函数内部的 a 就是 10 fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
-
注意: 箭头函数如果你需要使用默认值的话,那么一个参数的时候也需要写 ()
-
模板字符串
-
ES5 中我们表示字符串的时候使用
''
或者""
-
在 ES6 中,我们还有一个东西可以表示字符串,就是 ``(反引号)
let str = `hello world` console.log(typeof str) // string
-
和单引号还有双引号的区别
-
反引号可以换行书写
// 这个单引号或者双引号不能换行,换行就会报错了 let str = 'hello world' // 下面这个就报错了 let str2 = 'hello world' let str = ` hello world ` console.log(str) // 是可以使用的
-
反引号可以直接在字符串里面拼接变量
// ES5 需要字符串拼接变量的时候 let num = 100 let str = 'hello' + num + 'world' + num console.log(str) // hello100world100 // 直接写在字符串里面不好使 let str2 = 'hellonumworldnum' console.log(str2) // hellonumworldnum // 模版字符串拼接变量 let num = 100 let str = `hello${num}world${num}` console.log(str) // hello100world100
-
解构赋值
-
对象解构:可以快速读取对象中的属性或方法。
let {a = 1,b = 2,c = 3} = {c : 8,a : 2,b : 3}
-
数组解构: 可以快速读取数组中的元素。
let [a = 1,b = 2,c = 3] = [4,5,6];
-
好处?
-
可以快速交换两个变量中的值
-
函数中的形参可以设置默认值
-
函数中的形参可以不按照顺序传递
-
函数中的返回值可以一次返回多个数据了。
... 运算符(展开运算符)
-
ES6 里面号新添加了一个运算符
...
,叫做展开运算符 -
作用是把数组展开
let arr = [1, 2, 3, 4, 5] console.log(...arr) // 1 2 3 4 5
-
合并数组的时候可以使用
let arr = [1, 2, 3, 4] let arr2 = [...arr, 5] console.log(arr2)
-
也可以合并对象使用
let obj = { name: 'Jack', age: 18 } let obj2 = { ...obj, gender: '男' } console.log(obj2)
-
在函数传递参数的时候也可以使用
let arr = [1, 2, 3] function fn(a, b, c) { console.log(a) console.log(b) console.log(c) } fn(...arr) // 等价于 fn(1, 2, 3)
对象简写形式
当对象中的key和value的名字相同时,可以只写一个key.
let id = 1;
let name = '手机';
let price = 4999;
//创建一个对象
let obj = {
id, // id : id 名字相同,可以简写
name,
price,
num : 2
}
模块化语法 import / export
-
export : 导出模块
-
import : 导入模块
实现方法
-
先定义模块,再导出模块
//定义模块 let user = '张三'; let age = 18; function show(){ return '姓名' + user + '年龄' + age; } //导出模块 export {user,age,show}; //导入模块 import {user,age,show} from './tools.js';
-
边定义模块,边导出模块
//边定义模块,边导出模块 export let user = '张三'; export let age = 18; export function show(){ return `姓名${user},年龄${age}`; } //导入模块 import {user,age,show} from './tools.js';
-
以别名的方式导出模块
let a = '李四'; let b = 19; function c(){ return `姓名:${a},年龄:${b}`; } export {a as user,b as age,c as show}; //导入模块 import {user,age,show} from './tools.js';
-
导入 导出默认模块
//导出默认模块(只能有一个) let user = '王五'; let age = 20; function a(){ return `姓名:${user},年龄:${age}`; } export {user,age}; export default a; //导入模块 import {user,age} from './tools.js'; //导入默认模块 import display from './tools.js';
Set / Map / for ... of
Set : 天然具有去重的功能。
-
创建set对象
let set = new Set(); let set = new Set([1,2,1,2,1,2,3]);
-
属性
size : 长度
-
方法:
set.add(元素) : 添加元素,返回set对象 set.has(元素) : 检测元素是否在set对象中,返回布尔值 set.delete(元素) : 删除指定元素,返回布尔值 set.clear() : 清空set对象 set.forEach((value,key,set) =>{}) : 遍历set对象 set.keys() : 获取所有的key set.values() : 获取所有的value set.entries() : 获取所有的key和value for of
for(循环变量 of set|map){
语句组;
}
Map
-
创建map对象
let map = new Map(); let map = new Map([ [1,'one'], [2,'two'], ['2','three'], [true,'four'], [3,'five'] ]);
-
属性
size : 长度
-
方法:
map.set('key','value') : 添加元素,返回map对象 map.get('key') : 获取value map.has(元素) : 检测元素是否在map对象中,返回布尔值 map.delete(元素) : 删除指定元素,返回布尔值 map.clear() : 清空map对象 map.forEach((value,key,map) =>{}) : 遍历map对象 map.keys() : 获取所有的key map.values() : 获取所有的value map.entries() : 获取所有的key和value for of
for(循环变量 of set|map){
语句组;
}