携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
前言
大白话说JS内容包括:DOM的一些操作,Promise相关, 微任务宏任务,作用域,变量提升,闭包,变量类型,深浅拷贝,原型和作用域链,后续争取把js重点都记录上,深入浅出。
箭头函数和普通函数区别
箭头函数没有自己的this,他的this指向定义时所在的外层第一个普通函数,且 this指向永远不会改变,call、apply、bind 并不会影响其 this 的指向
没有原型prototype,不能作为构造函数使用(构造函数的this要是指向创建的新对象,但是箭头的this不会变),不能new,new了就报错
箭头函数没有自己的arguments参数,他的参数是外层普通函数的,取而代之用rest参数...代替arguments对象,来访问箭头函数的参数列表
let a = () => {};
console.log(a.prototype); // undefined
function a() {};
console.log(a.prototype); // {constructor:f}
let obj = {
a: 10,
b: () => {
console.log(this); // window
},
c: function() {
console.log(arguments);
console.log(this); // {a: 10, b: ƒ, c: ƒ}
}
}
obj.b();
obj.c();
// rest参数...
let C = (...c) => {
console.log(c);
}
C(3,82,32,11323); // [3, 82, 32, 11323]
this指向
- 默认是全局对象:window(普通函数调用和定时器函数指向也是window)
- 被构造函数调用时,,this指向该对象(谁调用指向谁)
- 对象的方法调用(绑定事件同理), this 指向该方法所属的对象
更改this指向:call() ,apply(),bind()
new操作符原理
- 创建一个类的实例:创建一个空对象obj,然后把这个空对象的
__proto__设置为构造函数的prototype。 - 初始化实例:构造函数被传入参数并调用,关键字this被设定指向该实例obj。
- 返回实例obj。
call ,apply, bind 方法及手写
这三个方法都是改变函数的this指向,期中call ,apply方法一样,只是传入的参数不同,详情见下面栗子,bind只是将结果以函数返回,接收后在调用即可,整体都是采用:B对象.方法.call(A,"参数")形式,表现为A对象要调用B的方法,下面看例子。
let dog = {
name: "小狗",
can (p1, p2) {
console.log('我会' + p1 + p2);
}
}
let cat = {
name: "小猫"
}
// dog.can.call(cat, "睡觉", "钓鱼");
// dog.can.apply(cat, ["睡觉", "钓鱼"]);
let fn = dog.can.bind(cat, "睡觉", "钓鱼");
fn();
不难看出 call ,apply, bind 的整体使用相差无几,根据原理,怎么手写该类方法呢?
Function.prototype.myCall = function(context){
if(typeof this !== "function"){
throw new TypeError("Error")
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)**加粗样式**
const result = context.fn(...args)
delete context.fn
return result
}
Function.prototype.myApply = function(context){
if(typeof this !== "function"){
throw new TypeError("Error")
}
context = context || window
context.fn = this
let result
if(arguments[1]){
result = context.fn(...arguments[1])
}else{
result = context.fn()
}
delete context.fn
return result
}
Function.prototype.myBind = function(context){
if(typeof this !== 'function'){
throw new TypeErroe('Error')
}
const _this = this
const args = [...arguments].slice(1)
return functions F(){
if(this instanceof F){
return new _this(...args,...arguments)
}
return _this.apply(context,args.concat(...arguments))
}
}