一.this指向
- this指向的概念: 每一个函数内部都有一个关键字this,this的值和函数的调用有关,与函数书写无关
- 一个普通的全局函数,在正常调用的情况下,this===window
- 如果将函数放置到对象,通过对象的语法去获取到并调用,那么 this === 对象
- 如果将函数作为事件处理函数,那么触发的时候,内部的this指向了事件源
- 如果将函数作为定时器执行时的函数,那么触发的时候,内部的this指向了全局对象window
function fn(){
console.log(this)
}
//1.普通调用方式
fn(); //this===window
//2.将函数fn赋值给对象obj的c属性fn和obj.c是一个引用地址
var obj={
a:1,
b:'我是对象obj的属性B',
c:fn
}
obj.c() //this===obj this指向l调用者
//3.事件的方式触发
var box=document.getElementById('box');
box.onclick=fn //this===box this指向了事件源
//4.倒计时器,定时器
setTimeout(fn, 0) // this === window
setInterval(fn, 1000) // this === window
二.改变this指向
var obj = {
a: 1,
b: 2,
c: '我是对象obj的属性c'
}
function fn(x, y) {
console.log(this, x, y)
}
fn(100, 200)
1.call() 帮助修改函数的this指向
- 语法: 函数.call(this指向谁,参数1,参数2,参数3...)第二个位置的参数,会传递给函数
2.apply() 修改函数this指向
- 语法: 函数.apply(this指向谁,[参数1,参数2,参数3]) 第二个位置的数组内数据,会传递到函数内部
3.bind() 修改函数的this指向
- 语法: 函数.bind(this指向谁,参数1,参数2,参数3...)第二个位置的参数开始,会传递给函数
- 注意点: bind 方法不会立即执行函数,会返回一个内部this修改完毕的新函数
var newFn = fn.bind(obj, 700, 800);
newFn()
三.ES6的了解
- ES6其实就是发展过程中的某一个版本而已,版本的版本号叫做ES6
- 微信在最初的时候,是不具有微信支付,随着版本的更新,在某一个版本内推出了微信支付
- js最初的时候,是只有var 关键可以声明变量,随着版本的更新,在某一个版本推出了新的变量声明方式
- js的更新,在推出ES6的时候,这个版本推出的新东西比较多,所以后续程序员们为了方便记忆,把ES6以后版本统称为ES6+
四.let与const
- ES6新增两种变量声明的方式
- ES5只能使用var 声明变量
- let与const和var语法一样
-
语法: let 变量名 = 值
-
语法: const 变量名 = 值
let与const与var 的差异
1.let与const 声明的变量不允许出现重复的
*使用var 声明变量的时候可以出现重复声明,后一个值会覆盖前一个值
*let/const不允许
2.let/const声明的变量没有变量提升
*var 关键字声明的变量有变量提升,值为undefined
*let/const不允许
3.let/const声明的变量会受限于所有{}
*也就是使用let/const声明的变量是块级作用域
*var 声明的变量只受限于函数内部
let与const的差异
1.let声明的叫做变量(后续可以修改内部的值);
*const声明的叫做常量(后续不能修改内部的值,也不能修改内部的引用地址)
2.因为let后续可以修改变量的值,所以首次定义时,可以不赋值
*但是const声明常量时,后续不能重新修改它的值,所以首次定义时,必须赋值
四.箭头函数
-
箭头函数就是多ES5普通函数写法上的一个优化
-
箭头函数 普通写法:(书写参数)=>{书写函数调用时执行的代码}
-
箭头函数的优化
- 箭头函数如果只有一个形参的时候,可以不写前边的小括号(除此之外,必写)
- 如果箭头函数的函数体,只有一行代码,那么可以省略大括号(并且会默认将这行代码 return)
五.解构赋值
- 解构赋值能快速从数组或对象中取出成员的一种语法
var arr = [1, 2];
// ES5 拿到数组所有成员的方法
var num1 = arr[0];
var num2 = arr[1];
var num3 = arr[2];
console.log(num1, num2, num3);
// ES6 解构赋值, 解构数组时, 赋值号左边必须写 中括号, 代表数组的解构赋值
let [num1, num2, num3] = arr;
console.log(num1, num2, num3);
var obj = {
a: 11,
b: 21,
c: 31
}
// ES5 拿到对象所有成员的方法
ar obj1 = obj.a;
var obj2 = obj.b;
var obj3 = obj.c;
console.log(obj1, obj2, obj3)
//ES6 解构赋值, 解构对象时, 赋值号左边 必须写大括号, 代表对象的解构赋值
//大括号内部必须书写对象的 key
let { a, b, c } = obj;
console.log(a, b, c);
六.箭头函数与普通函数的区别
- 箭头函数内部没有this;所以它的this取决于书写的时候
- 箭头函数内部没有argumets 对象
七.展开( 扩展 )运算符
-
语法: ...数组(对象)
-
作用: 展开数组或者对象,相当于把数组两侧包裹的中括号去掉
var arr = [1, 2, 3]; console.log(arr); console.log(...arr) var obj = { a: 1, b: 2 } console.log(obj); // console.log(...obj) JS 不支持这样的写法 var obj1 = { ...obj, a: 3, b: 4 } console.log(obj1); var arr = [1, 2, 3]; var arr1 = [...arr, 100, 200, 300]; console.log(arr); console.log(arr1); var arr = [1, 2, 3] function fn(a, b, c) { console.log(a, b, c) } fn(arr, 100, 200)
八.Map和Set (ES6新推出的两种数据结构)
一.Set
- set类似于数组的一种数据结构
- 内部按照索引排序(但是不能通过索引取值)
- 语法: let s = new Set([数据1,数据2,数据3])
- 特点: 天生不支持重复数据
var arr = [1, 2, 3, 4, 5];
console.log(arr);
// console.log(arr[0])
// 数组允许使用索引获取到对应的值, set 不允许
let s = new Set([3, 4, 5, 5, 5, 4, 4, 3]);
console.log('原始数据结构', s);
// console.log(s[0]) 数组允许使用索引获取到对应的值, set 不允许
-
size(类似数组的length);
-
作用:获取到当前数据结构中数据的数量
console.log(s.size)
-
add方法;
-
作用: 向当前数据结构中新增数据
s.add(100); s.add(5); console.log('add 后的数据结构', s);
-
has()
-
作用: 查询当前数据结构中是否拥有该数据; 找到时,返回true,否则返回false;
console.log(s.has(100)); console.log(s.has(5));
-
delete(数据)
-
作用: 将当前数据结构中这个数据删除
s.delete(5); console.log(s);
-
clear()
-
作用: 清空当前数据结构
s.clear(); console.log('清空后的数据结构 ', s);
-
forEach
-
作用: 遍历数组结构,拿到数据结构的每一项
s.forEach(function (item, key, origin) { // set 数据结构是没有 key 所以 item 和 key 打印出来的值都一样 console.log(item, key, origin) });二.Map
- Map是ES6推出的一种数据结构和Set一样,也不支持重复数据
- 类似于对象的一种数据类型,但是Map的key可以是任意类型的值
- 语法: var m = new Map([key,value]);
- 在实际开发中,我们使用Map的场景一般为想要将对象的key用于字符串之外的数据时使用
var arr = [1, 2, 3];
var arr1 = [4, 5, 6];
var m = new Map([[[500], [600]], [arr, arr1], ['arr123', arr1]]);
// console.log('原始数据结构: ', m)
-
size
-
作用: 返回当前数据结构中的数据长度(多少个)
console.log(m.size);
-
set()
-
作用: 向当前数据结构中,新增数据
m.set('newKey', [1, 2, 3, 4, 5]); console.log('set 新增数据后 的数据结构: ', m);
-
get(key)
-
作用: 获取到指定key对应的value
console.log(m.get(arr)); console.log(m.get('newKey'));
-
has(key)
-
作用: 查询数据结构中是否存在当前key;存在返回一个true, 否则返回一个false;
console.log(m.has('12345')); console.log(m.has('newKey'));
-
delete
-
作用: 删除当前数据结构对应的key
m.delete('newKey'); console.log(m);
-
clear
-
作用: 清空当前数据结构
m.clear(); console.log(m);
-
forEach
m.forEach(function (item, key, origin) { /* item: 对应的 value key: 对应的 key origin: 对应的原始数据结构 */ console.log(item, key, origin) })九.对象语法的简写
- key 和 value 拼写一样
- 并且 value 写的是一个变量
- 满足以上两个条件的情况, 可以少写 其中一个
//第一种方法: // console.log(window) // let name = 'QF666' // const obj = { // name: name, // age: 18, // } // const obj = { // name, // age: 18, // } // console.log(obj) /** * obj === { * name: 'QF666', * age: 18 * } */ //第二种方法: let name = 'QF666' const obj = { name, age: 18, fn1: function () { console.log(1) }, fn2() { console.log('222222') } } console.log(obj) obj.fn1() obj.fn2()十.模块化开发
<script type="module"> /** * 模块化开发: * 就是将功能拆分开, 每一个功能写到一个 JS 文件中 (整理出来 积木 一个个的模块) * 后续根据实际需求, 将不同的 JS 文件拼接到一起 (按照图纸, 将每一个积木拼接成一个 完整的 小汽车或者小房子) * * 将多个逻辑分别写道多个JS文件中 * 每一个文件, 都只能使用当前文件内的变量 * 每一个文件, 就是一个独立的作用域(文件作用域) * * ES6 使用 模块化开发的前提 * 1. 页面必须使用 服务器的形式打开 * 2. script 标签行内 必须配置 type="module" * * * 如果想要拼接的话, 需要导入别的文件到自己文件内 * 前提: 导入的文件, 必须有导出的内容 * * 导出: 向外部暴露出一些内容, 可以是变量, 也可以是函数 * 导入: 引入别的文件向外部暴露出的那些内容 */ </script>